public GatewayAddressCache( Uri serviceEndpoint, Protocol protocol, IAuthorizationTokenProvider tokenProvider, UserAgentContainer userAgent, IServiceConfigurationReader serviceConfigReader, long suboptimalPartitionForceRefreshIntervalInSeconds = 600, HttpMessageHandler messageHandler = null, ApiType apiType = ApiType.None) { this.addressEndpoint = new Uri(serviceEndpoint + "/" + Paths.AddressPathSegment); this.protocol = protocol; this.tokenProvider = tokenProvider; this.serviceEndpoint = serviceEndpoint; this.serviceConfigReader = serviceConfigReader; this.serverPartitionAddressCache = new AsyncCache <PartitionKeyRangeIdentity, PartitionAddressInformation>(); this.suboptimalServerPartitionTimestamps = new ConcurrentDictionary <PartitionKeyRangeIdentity, DateTime>(); this.suboptimalMasterPartitionTimestamp = DateTime.MaxValue; this.suboptimalPartitionForceRefreshIntervalInSeconds = suboptimalPartitionForceRefreshIntervalInSeconds; this.httpClient = messageHandler == null ? new HttpClient() : new HttpClient(messageHandler); this.protocolFilter = string.Format(CultureInfo.InvariantCulture, GatewayAddressCache.protocolFilterFormat, Constants.Properties.Protocol, GatewayAddressCache.ProtocolString(this.protocol)); // Set requested API version header for version enforcement. this.httpClient.DefaultRequestHeaders.Add(HttpConstants.HttpHeaders.Version, HttpConstants.Versions.CurrentVersion); this.httpClient.AddUserAgentHeader(userAgent); this.httpClient.AddApiTypeHeader(apiType); }
public async Task RunTimeOfFactoriesIsNotSumOfAllRuntimes() { var cache = new AsyncCache <int, int>(async x => { await Task.Delay(100); // simulate long job return(x * x); }); var stopwatch = Stopwatch.StartNew(); var tasks = new List <Task <int> >(100); for (int i = 0; i < 100; i++) { tasks.Add(cache.GetValueAsync(i)); } await Task.WhenAll(tasks); // 100 tasks that take 100ms should run under stopwatch.Stop(); Console.WriteLine($"Measured runtime is {stopwatch.ElapsedMilliseconds}ms"); stopwatch.ElapsedMilliseconds.Should().BeLessThan(300); // check for correct results. for (int i = 0; i < 100; i++) { var result = await tasks[i]; result.Should().Be(i * i); } }
public GlobalEndpointManager(IDocumentClientInternal owner, ConnectionPolicy connectionPolicy) { this.locationCache = new LocationCache( new ReadOnlyCollection <string>(connectionPolicy.PreferredLocations), owner.ServiceEndpoint, connectionPolicy.EnableEndpointDiscovery, connectionPolicy.MaxConnectionLimit, connectionPolicy.UseMultipleWriteLocations); this.owner = owner; this.defaultEndpoint = owner.ServiceEndpoint; this.connectionPolicy = connectionPolicy; this.databaseAccountCache = new AsyncCache <string, CosmosAccountSettings>(); this.connectionPolicy.PreferenceChanged += this.OnPreferenceChanged; this.isRefreshing = false; this.refreshLock = new object(); #if !(NETSTANDARD15 || NETSTANDARD16) string backgroundRefreshLocationTimeIntervalInMSConfig = System.Configuration.ConfigurationManager.AppSettings[GlobalEndpointManager.BackgroundRefreshLocationTimeIntervalInMS]; if (!string.IsNullOrEmpty(backgroundRefreshLocationTimeIntervalInMSConfig)) { if (!int.TryParse(backgroundRefreshLocationTimeIntervalInMSConfig, out this.backgroundRefreshLocationTimeIntervalInMS)) { this.backgroundRefreshLocationTimeIntervalInMS = GlobalEndpointManager.DefaultBackgroundRefreshLocationTimeIntervalInMS; } } #endif }
public async Task AfterCachingValuesCacheShouldHaveHighMultithreadedPerformance() { var cache = new AsyncCache <int, int>(x => x * x) { ItemLimit = 800, AutomaticCleanup = false }; // below active count // dry run Func <int, Task> job = n => Task.Run(() => { for (int i = 0; i < 1000; i++) { cache.GetValue(i % 1000); } }); // performs optimizations cache.OptimizeEvery = TimeSpan.Zero; // after any time passed await cache.CleanupAsync(); Stopwatch stopwatch = new Stopwatch(); // benchmark stopwatch.Start(); await Task.WhenAll(Enumerable.Range(1, 10).Select(job).ToList()); stopwatch.Stop(); var elapsed = stopwatch.Elapsed; elapsed.Should().BeLessThan(new TimeSpan(0, 0, 0, 1)); }
public GatewayAddressCache( Uri serviceEndpoint, Protocol protocol, IAuthorizationTokenProvider tokenProvider, IServiceConfigurationReader serviceConfigReader, CosmosHttpClient httpClient, long suboptimalPartitionForceRefreshIntervalInSeconds = 600, bool enableTcpConnectionEndpointRediscovery = false) { this.addressEndpoint = new Uri(serviceEndpoint + "/" + Paths.AddressPathSegment); this.protocol = protocol; this.tokenProvider = tokenProvider; this.serviceEndpoint = serviceEndpoint; this.serviceConfigReader = serviceConfigReader; this.serverPartitionAddressCache = new AsyncCache <PartitionKeyRangeIdentity, PartitionAddressInformation>(); this.suboptimalServerPartitionTimestamps = new ConcurrentDictionary <PartitionKeyRangeIdentity, DateTime>(); this.serverPartitionAddressToPkRangeIdMap = new ConcurrentDictionary <ServerKey, HashSet <PartitionKeyRangeIdentity> >(); this.suboptimalMasterPartitionTimestamp = DateTime.MaxValue; this.enableTcpConnectionEndpointRediscovery = enableTcpConnectionEndpointRediscovery; this.suboptimalPartitionForceRefreshIntervalInSeconds = suboptimalPartitionForceRefreshIntervalInSeconds; this.httpClient = httpClient; this.protocolFilter = string.Format(CultureInfo.InvariantCulture, GatewayAddressCache.protocolFilterFormat, Constants.Properties.Protocol, GatewayAddressCache.ProtocolString(this.protocol)); }
public async Task AsyncCacheTest() { // Initialize the cache AsyncCache <string, string> m_webPages = new AsyncCache <string, string>((url) => { return(Task.Factory.StartNew(() => { Task.Delay(10 * url[0]); return Guid.NewGuid().ToString(); })); }); // Use the cache Stopwatch clock = new Stopwatch(); clock.Start(); string result = await m_webPages["https://www.google.com"]; clock.Stop(); Debug.WriteLine("Result: " + result + "Delay: " + clock.Elapsed); Debug.WriteLine(await m_webPages["abcd"]); clock.Reset(); clock.Start(); string result2 = await m_webPages["https://www.google.com"]; Debug.WriteLine("Result: " + result2 + "Delay: " + clock.Elapsed); }
public async Task FactoryExceptionWillDiscardValueAndRethrow() { var counter = 0; var exceptionCounter = 0; var cache = new AsyncCache <int, int>(); cache.AsyncFactory = async x => { counter++; throw new InvalidOperationException("nope"); }; for (int i = 0; i < 10; i++) { try { var cacheTask = await cache.GetValueAsync(3); } catch (InvalidOperationException) { exceptionCounter++; } } counter.Should().Be(10); exceptionCounter.Should().Be(10); }
public TrackerPullRequest(IPullRequest gitPullRequest, ConcurrentDictionary <string, BitmapImage> avatarCache, AsyncCache <string, BitmapImage> avatarDownloadAsyncCache, string reviewTool) { this.gitPullRequest = gitPullRequest; this.avatarCache = avatarCache; this.avatarDownloadAsyncCache = avatarDownloadAsyncCache; this.ReviewTool = reviewTool; }
public async Task CanFilterValues() { var counter = 0; var cache = new AsyncCache <int, int>(x => { counter++; return(x * x); }); cache.Filter = x => x != 0; // only cache non zero results cache.GetValue(1); cache.GetValue(1); counter.Should().Be(1); cache.GetValue(0); cache.GetValue(0); counter.Should().Be(3); await cache.GetValueAsync(1); await cache.GetValueAsync(1); counter.Should().Be(3); await cache.GetValueAsync(0); await cache.GetValueAsync(0); counter.Should().Be(5); }
public TrackerPullRequest(IPullRequest gitPullRequest, ConcurrentDictionary <string, BitmapImage> avatarCache, AsyncCache <string, BitmapImage> avatarDownloadAsyncCache, TrackerQuery query) { this.gitPullRequest = gitPullRequest; this.avatarCache = avatarCache; this.avatarDownloadAsyncCache = avatarDownloadAsyncCache; this.Query = query; }
public async Task CanOverrideFactoryWhenGettingValue() { var cache = new AsyncCache <int, int>(x => x * x); (await cache.GetValueAsync(3, x => x + x)).Should().Be(6); cache.GetValue(3, x => x + x).Should().Be(6); }
public async Task PurgingShouldNotAffectResults() { var cache = new AsyncCache <int, int>(x => x * x) { ItemLimit = 10 // this should force a lot of recycling }; var threadActive = true; var thread = new Thread(() => { while (threadActive) { cache.CleanupAsync().Wait(); } }); thread.Start(); Func <int, Task> job = n => Task.Run(() => { for (int i = 0; i < 1000; i++) { cache.GetValue(i); } }); await Task.WhenAll(Enumerable.Range(1, 10).Select(job).ToList()); threadActive = false; thread.Join(); }
public async Task OldUpdateOperationCanceledOnUpdateTest() { var revision = 0; CancellationToken cancellation; async Task <int> update(CancellationToken c) { var r = Interlocked.Increment(ref revision); if (r == 1) { cancellation = c; } await Task.Delay(50, c); return(r); } var asyncCache = new AsyncCache <int>(update); asyncCache.Update(); asyncCache.Update(); Assert.IsTrue(cancellation.IsCancellationRequested); Assert.AreEqual(revision, await asyncCache.Task); }
public async Task TestCancelOnOneThreadCancelsOtherTaskIfCanceled() { AsyncCache <int, int> cache = new AsyncCache <int, int>(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); SemaphoreSlim resetEventSlim = new SemaphoreSlim(0, 1); bool generatorFunc2Called = false; Func <Task <int> > generatorFunc1 = () => Task.Run(async() => { await resetEventSlim.WaitAsync(cancellationTokenSource.Token); return(1); }, cancellationTokenSource.Token); Func <Task <int> > generatorFunc2 = () => Task.Run(() => { generatorFunc2Called = true; return(2); }); // set up two threads that are concurrently updating the async cache for the same key. // the only difference is that one thread passes in a cancellation token // and the other does not. Task <int> getTask1 = cache.GetAsync(key: 1, obsoleteValue: -1, singleValueInitFunc: generatorFunc1, cancellationToken: cancellationTokenSource.Token); Task <int> getTask2 = cache.GetAsync(key: 1, obsoleteValue: -1, singleValueInitFunc: generatorFunc2, cancellationToken: cancellationTokenSource.Token); // assert that the tasks haven't completed. Assert.IsFalse(getTask2.IsCompleted); Assert.IsFalse(getTask1.IsCompleted); // cancel the first task's cancellation token. cancellationTokenSource.Cancel(); // neither task is complete at this point. Assert.IsFalse(getTask2.IsCompleted); Assert.IsFalse(getTask1.IsCompleted); try { await getTask1; Assert.Fail("Should fail because of cancellation."); } catch (Exception e) { Assert.IsTrue(e as OperationCanceledException != null, e.Message); } try { await getTask2; Assert.Fail("Should fail because of cancellation."); } catch (Exception e) { Assert.IsTrue(e as OperationCanceledException != null, e.Message); } Assert.IsFalse(generatorFunc2Called); }
internal static void OnAfterBlockingLoadInto(AsyncCache asynccache, Interop.DBObj dbobj, QualifiedDataID qdid, DBOCache dbocache) { if (!Caches.CacheDictPtr.TryGetValue(dbocache.__Instance, out var dbocacheex)) { return; } dbocacheex.OnAfterBlockingLoadIntoBase(dbobj, qdid); }
public VersionedCache(ISchemaVersionResolver schemaVersionResolver, IEnumerable <T> versionedEntities) { _schemaVersionResolver = EnsureArg.IsNotNull(schemaVersionResolver, nameof(schemaVersionResolver)); _entities = EnsureArg.IsNotNull(versionedEntities, nameof(versionedEntities)) .Where(x => x != null) .OrderByDescending(x => x.Version); _cache = new AsyncCache <T>(ResolveAsync); }
public DefaultExchangeDeclareStrategy(IConventions conventions, IAdvancedBus advancedBus) { Preconditions.CheckNotNull(conventions, "conventions"); Preconditions.CheckNotNull(advancedBus, "advancedBus"); this.conventions = conventions; declaredExchanges = new AsyncCache <ExchangeKey, IExchange>((k, c) => advancedBus.ExchangeDeclareAsync(k.Name, k.Type, cancellationToken: c)); }
public void DoesNotDeadlockOnAsyncApi() { using (var context = new AsyncContext(threadCount: 0, borrowsCallerThread: true)) { context.Run(async() => { var cache = new AsyncCache <int, int> { AutomaticCleanup = true, ItemLimit = 200, // make sure we hit this as well DefaultCacheCallOptions = new CacheCallOptions <int, int> { // this option causes the cache to dispatch much more slowly // !and is essentiall for this test! CacheMissAction = () => Thread.Sleep(100), AsyncFactory = async x => { // schedule a bunch of stuff await Task.WhenAll( Task.Run(() => Task.Delay(100)), Task.Run(() => Task.Delay(100)), Task.Run(() => Task.Delay(100)), Task.Run(() => Task.Delay(100))); return(x * x); } } }; var clients = 10; var syncronizedStart = new SemaphoreSlim(0); Console.WriteLine($"Preparing {clients} clients..."); var threads = Enumerable.Range(0, clients).Select(id => new Thread(() => { syncronizedStart.Wait(); var value = cache.GetValueAsync(id).Result; })).ToList(); foreach (var thread in threads) { thread.Start(); } Console.WriteLine($"Starting in 1 sec..."); await Task.Delay(1000); Console.WriteLine($"Starting..."); syncronizedStart.Release(clients); foreach (var thread in threads) { // if thread doesnt finish in 10 seconds, it's pretty much deadlocked if (thread.Join(2000) == false) { // to debug put breakpoint here, and look at what the threads are doing Assert.Fail(); } } Console.WriteLine($"Done!"); }); } }
public PartitionKeyRangeCache(IAuthorizationTokenProvider authorizationTokenProvider, IStoreModel storeModel, CollectionCache collectionCache) { this.routingMapCache = new AsyncCache <string, CollectionRoutingMap>( EqualityComparer <CollectionRoutingMap> .Default, StringComparer.Ordinal); this.authorizationTokenProvider = authorizationTokenProvider; this.storeModel = storeModel; this.collectionCache = collectionCache; }
public async Task WillCacheFactoryResult(bool blockingGet, bool asyncFactory, bool useTasks) { int counter = 0; var cache = new AsyncCache <int, int>(); if (asyncFactory) { cache.AsyncFactory = async x => { await Task.Delay(1); Interlocked.Increment(ref counter); return(x * x); }; } else { cache.Factory = x => { Interlocked.Increment(ref counter); return(x * x); }; } async Task Job() { for (int i = 0; i < 10; i++) { int value; if (blockingGet) { value = cache.GetValue(i); } else { value = await cache.GetValueAsync(i); } value.Should().Be(i * i); } } if (useTasks) { var tasks = Enumerable.Range(1, 10).Select(n => Task.Run((Func <Task>)Job)); await Task.WhenAll(tasks); } else { // prepare the threads var threads = Enumerable.Range(1, 10).Select(n => new Thread(() => Job().Wait())).ToList(); // start all the theads threads.ForEach(thread => thread.Start()); threads.ForEach(thread => thread.Join()); } // done? => counter should be 10 counter.Should().Be(10); }
/// <summary> /// Initializes a new instance of the <see cref="StreamOriginatedDicomInstanceEntry"/> class. /// </summary> /// <param name="seekableStream">The stream.</param> /// <remarks>The <paramref name="seekableStream"/> must be seekable.</remarks> internal StreamOriginatedDicomInstanceEntry(Stream seekableStream) { // The stream must be seekable. EnsureArg.IsNotNull(seekableStream, nameof(seekableStream)); EnsureArg.IsTrue(seekableStream.CanSeek, nameof(seekableStream)); _stream = seekableStream; _dicomFileCache = new AsyncCache <DicomFile>(_ => DicomFile.OpenAsync(_stream, FileReadOption.SkipLargeTags)); }
public async void SmokeTestSyncMissHit() { var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}"); Directory.CreateDirectory(path); AsyncCache cache = null; try { var asyncCacheOptions = new AsyncCacheOptions() { MaxQueuedBytes = 0 }; var builder = new HashBasedPathBuilder(path, 8192, '/', ".jpg"); cache = new AsyncCache(asyncCacheOptions, new NullCacheManager(), builder, null); var keyBasis = new byte[] { 6, 1, 2 }; var result = await cache.GetOrCreateBytes(keyBasis, (token) => { return(Task.FromResult(new Tuple <string, ArraySegment <byte> >( null, new ArraySegment <byte>(new byte[] { 3, 2, 1 })))); }, CancellationToken.None, false); Assert.NotNull(result.Data); Assert.Equal("WriteSucceeded", result.Status); await cache.AwaitEnqueuedTasks(); var result2 = await cache.GetOrCreateBytes(keyBasis, (token) => { return(Task.FromResult(new Tuple <string, ArraySegment <byte> >( null, new ArraySegment <byte>(new byte[] { 3, 2, 1 })))); }, CancellationToken.None, false); Assert.NotNull(result2.Data); Assert.Equal("DiskHit", result2.Status); var hash = builder.HashKeyBasis(keyBasis); var expectedPhysicalPath = builder.GetPhysicalPathFromHash(hash); Assert.True(File.Exists(expectedPhysicalPath)); } finally { try { await cache?.AwaitEnqueuedTasks(); } finally { Directory.Delete(path, true); } } }
public async Task TestGetAsync() { int numberOfCacheRefreshes = 0; Func <int, CancellationToken, Task <int> > refreshFunc = (key, cancellationToken) => { Interlocked.Increment(ref numberOfCacheRefreshes); return(Task.FromResult(key * 2)); }; AsyncCache <int, int> cache = new AsyncCache <int, int>(); List <Task> tasks = new List <Task>(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { int key = j; tasks.Add(cache.GetAsync(key, -1, () => refreshFunc(key, CancellationToken.None), CancellationToken.None)); } } await Task.WhenAll(tasks); Assert.AreEqual(10, numberOfCacheRefreshes); Assert.AreEqual(4, await cache.GetAsync(2, -1, () => refreshFunc(2, CancellationToken.None), CancellationToken.None)); Func <int, CancellationToken, Task <int> > refreshFunc1 = (key, cancellationToken) => { Interlocked.Increment(ref numberOfCacheRefreshes); return(Task.FromResult(key * 2 + 1)); }; List <Task> tasks1 = new List <Task>(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { int key = j; tasks1.Add(cache.GetAsync(key, key * 2, () => refreshFunc1(key, CancellationToken.None), CancellationToken.None)); } for (int j = 0; j < 10; j++) { int key = j; tasks1.Add(cache.GetAsync(key, key * 2, () => refreshFunc1(key, CancellationToken.None), CancellationToken.None)); } } await Task.WhenAll(tasks1); Assert.AreEqual(20, numberOfCacheRefreshes); Assert.AreEqual(5, await cache.GetAsync(2, -1, () => refreshFunc(2, CancellationToken.None), CancellationToken.None)); }
public async Task CanProvideFactoryAtCallTime() { var cache = new AsyncCache <int, int>(); var result = cache.GetValue(3, x => x * x);; result.Should().Be(9); var result2 = await cache.GetValueAsync(5, x => x + x);; result2.Should().Be(10); }
public async Task CacheMissActionCanDenyFactoryCall() { var cache = new AsyncCache <int, int>(x => x * x); var options = new CacheCallOptions <int, int>(); options.CacheMissAction = () => { options.DontCallFactory = true; }; cache.GetValue(3, options).Should().Be(0); (await cache.GetValueAsync(3, options)).Should().Be(0); }
public async Task UpdateOperationThrowsTest() { async Task <int> update(CancellationToken c) { await Task.Delay(5); throw new InvalidTimeZoneException(); } var asyncCache = new AsyncCache <int>(update); await Assert.ThrowsExceptionAsync <InvalidTimeZoneException>(async() => await asyncCache.Task); }
public async Task GivenARequestForAKey_WhenASecondRequestForADifferentKeyIsIssued_ThenTheExpensiveOperationIsPerformedAgain() { var cache = new AsyncCache <string>(TimeSpan.FromMinutes(10)); var task1 = cache.AddOrGetExisting("Key1", () => PerformExpensiveTask("Key1")); await Task.Delay(100); var task2 = cache.AddOrGetExisting("Key2", () => PerformExpensiveTask("Key2")); var results = await Task.WhenAll(task1, task2); Assert.Equal("Key1 Result", results[0]); Assert.Equal("Key2 Result", results[1]); Assert.Equal(_expensiveTaskCallCount, 2); }
public async Task GivenARequestForAKeyFailed_WhenTheSameKeyIsQueriedAgainSomeTimeLater_ThenTheExpensiveOperationIsPerformedAgain() { var cache = new AsyncCache <string>(TimeSpan.FromMinutes(10)); var task1 = Assert.ThrowsAsync <ArgumentException>(() => cache.AddOrGetExisting("Key1", () => PerformExpensiveTask("Key1", true))); await Task.Delay(600); var task2 = cache.AddOrGetExisting("Key1", () => PerformExpensiveTask("Key1", false)); await Task.WhenAll(task1, task2); Assert.NotNull(task1.Result); Assert.Equal("Key1 Result", task2.Result); Assert.Equal(_expensiveTaskCallCount, 2); }
public TcpIpSystem(TcpIpSystemParam param) : base(param) { LocalHostPossibleGlobalIpAddressListCache = new AsyncCache <HashSet <IPAddress> >(CoresConfig.TcpIpSystemSettings.LocalHostPossibleGlobalIpAddressListCacheLifetime, CacheFlags.IgnoreUpdateError | CacheFlags.NoGc, GetLocalHostPossibleGlobalIpAddressListMainAsync); DnsResolverSingleton = new Singleton <DnsResolver>(() => CreateDnsResolverImpl()); this.HostInfoCache = new CachedProperty <TcpIpSystemHostInfo>(getter: () => this.GetHostInfo(true), expiresLifeTimeMsecs: CoresConfig.TcpIpSystemSettings.HostHostInfoCacheLifetime); this.EasyHostNameToIpCache = new AsyncCache <string, IPAddress>(CoresConfig.TcpIpSystemSettings.EasyHostNameToIpCacheLifetime, CacheFlags.IgnoreUpdateError | CacheFlags.NoGc, async(hostname, cancel) => await this.GetIpAsync(hostname, cancel: cancel, orderBy: ip => (long)ip.AddressFamily)); }
internal Music(string apiKey, HttpClient client, string storage) { this.apiKey = apiKey; this.storage = storage; this.client = client; this.expiry = TimeSpan.FromDays(Settings.Default.FanartCacheDays); this.serializer = new MusicSerializer(); this.cache = new AsyncCache<string, Artist>(id => { return GetArtistByMusicBrainzIdInternalAsync(id); }); this.Load(); }
public void Test_CoordinationDataStructures_AsyncCoordination_AsyncCache_Cache() { //异步cached var asyncCache = new AsyncCache <int, int>(e => Task.Factory.StartNew <int>(() => 10)); var task = asyncCache.GetValue(1); Assert.AreEqual(true, task.IsCompleted); Assert.AreEqual(1, task.Result); var httpCache = new HtmlAsyncCache(); var pageTask = httpCache.GetValue(new Uri("http://www.baidu.com")); Assert.AreEqual(true, pageTask.IsCompleted); }
public CacheController() { _movieCache = new AsyncCache<string, AsyncCache<string, MovieInfo>>((movieKey) => { var movieProcTask = RequestProcessor.CreateMovieRequestIterator(movieKey).Run<MovieInfo>(); return movieProcTask.ContinueWith((taskMovie) => { return new AsyncCache<string, MovieInfo>((languageKey) => { return RequestProcessor.CreateTranslatorRequestIterator(languageKey, new MovieInfo(taskMovie.Result)).Run<MovieInfo>(); }); }); }); }
private void CreateCaches() { _servers = new AsyncCache<Server, API.Models.ServerReference>( (key, parentKey) => { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Created server {key}."); return new Server(key, this); }, (server, model) => { server.Name = model.Name; _channels.Update(server.DefaultChannelId, server.Id, null); if (model is ExtendedServerInfo) { var extendedModel = model as ExtendedServerInfo; server.AFKChannelId = extendedModel.AFKChannelId; server.AFKTimeout = extendedModel.AFKTimeout; server.JoinedAt = extendedModel.JoinedAt ?? DateTime.MinValue; server.OwnerId = extendedModel.OwnerId; server.Region = extendedModel.Region; foreach (var role in extendedModel.Roles) _roles.Update(role.Id, model.Id, role); foreach (var channel in extendedModel.Channels) _channels.Update(channel.Id, model.Id, channel); foreach (var membership in extendedModel.Members) { _users.Update(membership.User.Id, membership.User); server.UpdateMember(membership); } foreach (var membership in extendedModel.VoiceStates) server.UpdateMember(membership); foreach (var membership in extendedModel.Presences) server.UpdateMember(membership); } if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Updated server {server.Name} ({server.Id})."); }, server => { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Destroyed server {server.Name} ({server.Id})."); } ); _channels = new AsyncCache<Channel, API.Models.ChannelReference>( (key, parentKey) => { if (_isDebugMode) { if (parentKey != null) RaiseOnDebugMessage(DebugMessageType.Cache, $"Created channel {key} in server {parentKey}."); else RaiseOnDebugMessage(DebugMessageType.Cache, $"Created private channel {key}."); } return new Channel(key, parentKey, this); }, (channel, model) => { channel.Name = model.Name; channel.Type = model.Type; if (model is ChannelInfo) { var extendedModel = model as ChannelInfo; channel.Position = extendedModel.Position; if (extendedModel.IsPrivate) { var user = _users.Update(extendedModel.Recipient.Id, extendedModel.Recipient); channel.RecipientId = user.Id; user.PrivateChannelId = channel.Id; } if (extendedModel.PermissionOverwrites != null) { channel.PermissionOverwrites = extendedModel.PermissionOverwrites.Select(x => new Channel.PermissionOverwrite { Type = x.Type, Id = x.Id, Deny = new PackedPermissions(x.Deny), Allow = new PackedPermissions(x.Allow) }).ToArray(); } else channel.PermissionOverwrites = null; } if (_isDebugMode) { if (channel.IsPrivate) RaiseOnDebugMessage(DebugMessageType.Cache, $"Updated private channel {channel.Name} ({channel.Id})."); else RaiseOnDebugMessage(DebugMessageType.Cache, $"Updated channel {channel.Name} ({channel.Id}) in server {channel.Server?.Name} ({channel.ServerId})."); } }, channel => { if (channel.IsPrivate) { var user = channel.Recipient; if (user.PrivateChannelId == channel.Id) user.PrivateChannelId = null; if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Destroyed private channel {channel.Name} ({channel.Id})."); } else { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Destroyed channel {channel.Name} ({channel.Id}) in server {channel.Server?.Name} ({channel.ServerId})."); } }); _messages = new AsyncCache<Message, API.Models.MessageReference>( (key, parentKey) => { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Created message {key} in channel {parentKey}."); return new Message(key, parentKey, this); }, (message, model) => { if (model is API.Models.Message) { var extendedModel = model as API.Models.Message; if (extendedModel.Attachments != null) { message.Attachments = extendedModel.Attachments.Select(x => new Message.Attachment { Id = x.Id, Url = x.Url, ProxyUrl = x.ProxyUrl, Size = x.Size, Filename = x.Filename, Width = x.Width, Height = x.Height }).ToArray(); } else message.Attachments = new Message.Attachment[0]; if (extendedModel.Embeds != null) { message.Embeds = extendedModel.Embeds.Select(x => { var embed = new Message.Embed { Url = x.Url, Type = x.Type, Description = x.Description, Title = x.Title }; if (x.Provider != null) { embed.Provider = new Message.EmbedReference { Url = x.Provider.Url, Name = x.Provider.Name }; } if (x.Author != null) { embed.Author = new Message.EmbedReference { Url = x.Author.Url, Name = x.Author.Name }; } if (x.Thumbnail != null) { embed.Thumbnail = new Message.File { Url = x.Thumbnail.Url, ProxyUrl = x.Thumbnail.ProxyUrl, Width = x.Thumbnail.Width, Height = x.Thumbnail.Height }; } return embed; }).ToArray(); } else message.Embeds = new Message.Embed[0]; message.IsMentioningEveryone = extendedModel.IsMentioningEveryone; message.IsTTS = extendedModel.IsTextToSpeech; message.MentionIds = extendedModel.Mentions?.Select(x => x.Id)?.ToArray() ?? new string[0]; message.IsMentioningMe = message.MentionIds.Contains(_myId); message.RawText = extendedModel.Content; message.Timestamp = extendedModel.Timestamp; message.EditedTimestamp = extendedModel.EditedTimestamp; if (extendedModel.Author != null) message.UserId = extendedModel.Author.Id; } if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Updated message {message.Id} in channel {message.Channel?.Name} ({message.ChannelId})."); }, message => { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Destroyed message {message.Id} in channel {message.Channel?.Name} ({message.ChannelId})."); } ); _roles = new AsyncCache<Role, API.Models.Role>( (key, parentKey) => { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Created role {key} in server {parentKey}."); return new Role(key, parentKey, this); }, (role, model) => { role.Name = model.Name; role.Permissions.RawValue = (uint)model.Permissions; if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Updated role {role.Name} ({role.Id}) in server {role.Server?.Name} ({role.ServerId})."); }, role => { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Destroyed role {role.Name} ({role.Id}) in server {role.Server?.Name} ({role.ServerId})."); } ); _users = new AsyncCache<User, API.Models.UserReference>( (key, parentKey) => { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Created user {key}."); return new User(key, this); }, (user, model) => { user.AvatarId = model.Avatar; user.Discriminator = model.Discriminator; user.Name = model.Username; if (model is SelfUserInfo) { var extendedModel = model as SelfUserInfo; user.Email = extendedModel.Email; user.IsVerified = extendedModel.IsVerified; } if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Updated user {user?.Name} ({user.Id})."); }, user => { if (_isDebugMode) RaiseOnDebugMessage(DebugMessageType.Cache, $"Destroyed user {user?.Name} ({user.Id})."); } ); }
internal Server(string id, DiscordClient client) { Id = id; _client = client; _bans = new ConcurrentDictionary<string, bool>(); _members = new AsyncCache<Membership, API.Models.MemberInfo>( (key, parentKey) => { if (_client.IsDebugMode) _client.RaiseOnDebugMessage(DebugMessageType.Cache, $"Created user {key} in server {parentKey}."); return new Membership(parentKey, key, _client); }, (member, model) => { if (model is API.Models.PresenceMemberInfo) { var extendedModel = model as API.Models.PresenceMemberInfo; member.Status = extendedModel.Status; member.GameId = extendedModel.GameId; } if (model is API.Models.VoiceMemberInfo) { var extendedModel = model as API.Models.VoiceMemberInfo; member.VoiceChannelId = extendedModel.ChannelId; member.IsDeafened = extendedModel.IsDeafened; member.IsMuted = extendedModel.IsMuted; if (extendedModel.IsSelfDeafened.HasValue) member.IsSelfDeafened = extendedModel.IsSelfDeafened.Value; if (extendedModel.IsSelfMuted.HasValue) member.IsSelfMuted = extendedModel.IsSelfMuted.Value; member.IsSuppressed = extendedModel.IsSuppressed; member.SessionId = extendedModel.SessionId; member.Token = extendedModel.Token; } if (model is API.Models.RoleMemberInfo) { var extendedModel = model as API.Models.RoleMemberInfo; member.RoleIds = extendedModel.Roles; if (extendedModel.JoinedAt.HasValue) member.JoinedAt = extendedModel.JoinedAt.Value; } if (model is API.Models.InitialMemberInfo) { var extendedModel = model as API.Models.InitialMemberInfo; member.IsDeafened = extendedModel.IsDeafened; member.IsMuted = extendedModel.IsMuted; } if (_client.IsDebugMode) _client.RaiseOnDebugMessage(DebugMessageType.Cache, $"Updated user {member.User?.Name} ({member.UserId}) in server {member.Server?.Name} ({member.ServerId})."); }, (member) => { if (_client.IsDebugMode) _client.RaiseOnDebugMessage(DebugMessageType.Cache, $"Destroyed user {member.User?.Name} ({member.UserId}) in server {member.Server?.Name} ({member.ServerId})."); } ); }