public async Task GetAutoReloadDataWithIntervalTestsAsync(bool shouldReloadInBackground) { ICacheInstance cache = MemoryCache.GetNamedInstance(Guid.NewGuid().ToString()); var key = Guid.NewGuid().ToString(); var dataReloadInterval = TimeSpan.FromMilliseconds(200); var ref1 = GetOrCreate(cache, key, dataReloadInterval, shouldReloadInBackground: shouldReloadInBackground); await Task.Delay(TimeSpan.FromMilliseconds(100)); var ref2 = GetOrCreate(cache, key, dataReloadInterval, shouldReloadInBackground: shouldReloadInBackground); await Task.Delay(TimeSpan.FromMilliseconds(150)); var ref3 = GetOrCreate(cache, key, dataReloadInterval, shouldReloadInBackground: shouldReloadInBackground); await Task.Delay(TimeSpan.FromMilliseconds(100)); var ref4 = GetOrCreate(cache, key, dataReloadInterval, shouldReloadInBackground: shouldReloadInBackground); ref1.Should().Be(ref2); if (shouldReloadInBackground) { ref2.Should().Be(ref3); ref3.Should().NotBe(ref4); } else { ref2.Should().NotBe(ref3); ref3.Should().Be(ref4); } }
public async Task TestAutoReloadOnExceptionAsync(bool shouldReloadInBackground) { ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestAutoReloadOnExceptionAsync)); var key = Guid.NewGuid().ToString(); var data = cache.GetAutoReloadDataWithInterval(key, () => 8, TimeSpan.MaxValue, TimeSpan.FromMilliseconds(100), shouldReloadInBackground: shouldReloadInBackground); data.Should().Be(8); var exceptionCount = 0; Func <Task <int> > exceptionFunc = async() => { await Task.Delay(RandomUtils.Random.Next(20) + 20).ConfigureAwait(false); Interlocked.Increment(ref exceptionCount); throw new InvalidOperationException(); }; for (var i = 0; i < 10; i++) { await Task.Delay(150); using (new PerfMonitorScope(sw => Console.WriteLine($"[{i}] {sw.ElapsedMilliseconds}ms"))) { data = cache.GetAutoReloadDataWithInterval(key, exceptionFunc, TimeSpan.MaxValue, TimeSpan.FromMilliseconds(100), shouldReloadInBackground: shouldReloadInBackground); } if (shouldReloadInBackground) { await Task.Delay(80); using (new PerfMonitorScope(sw => Console.WriteLine($"[{i}] {sw.ElapsedMilliseconds}ms"))) { data = cache.GetAutoReloadDataWithInterval(key, exceptionFunc, TimeSpan.MaxValue, TimeSpan.FromMilliseconds(100), shouldReloadInBackground: shouldReloadInBackground); } } data.Should().Be(8); exceptionCount.Should().Be(i + 1); } await Task.Delay(150); using (new PerfMonitorScope(sw => Console.WriteLine($"{sw.ElapsedMilliseconds}ms"))) { data = cache.GetAutoReloadDataWithInterval(key, () => 6, TimeSpan.MaxValue, TimeSpan.FromMilliseconds(100), shouldReloadInBackground: shouldReloadInBackground); } if (shouldReloadInBackground) { await Task.Delay(80); data.Should().Be(8); using (new PerfMonitorScope(sw => Console.WriteLine($"{sw.ElapsedMilliseconds}ms"))) { data = cache.GetAutoReloadDataWithInterval(key, exceptionFunc, TimeSpan.MaxValue, TimeSpan.FromMilliseconds(100), shouldReloadInBackground: shouldReloadInBackground); } } data.Should().Be(6); }
public void TestDeleteKey() { ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestDeleteKey)); var key = Guid.NewGuid().ToString(); cache.SetData(key, new object(), TimeSpan.MaxValue); cache.TryDeleteKey(key).Should().BeTrue(); cache.TryDeleteKey(key).Should().BeFalse(); }
public static ICacheInstance GetNamedInstance(string name) { _ = name ?? throw new ArgumentNullException(nameof(name)); ICacheInstance result = s_namedCacheInstances.GetOrAdd( name, key => new MemoryCacheInstance(name)); return(result); }
public static ICacheInstance GetCurrentClassNamedCacheInstance() { var callingMethod = new StackTrace().GetFrame(1).GetMethod(); var name = callingMethod.DeclaringType.FullName; ICacheInstance result = s_namedCacheInstances.GetOrAdd( name, key => new MemoryCacheInstance(name)); return(result); }
public void TestGetAutoReloadDataWithCache_SetAsyncDataOnException() { ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestGetAutoReloadDataWithInterval_SetAsyncDataOnException)); var key = Guid.NewGuid().ToString(); var obj = cache.GetAutoReloadDataWithCache(key, async() => new object(), async() => key, TimeSpan.MaxValue, TimeSpan.MaxValue); obj.Should().NotBeNull(); cache.GetAutoReloadDataWithCache <object>(key, async() => throw new InvalidOperationException("dummy"), async() => key, TimeSpan.MaxValue, TimeSpan.MaxValue).Should().Be(obj); Action act = () => cache.GetAutoReloadDataWithCache <object>(Guid.NewGuid().ToString(), () => throw new InvalidOperationException("dummy"), async() => key, TimeSpan.MaxValue, TimeSpan.MaxValue); act.Should().Throw <InvalidOperationException>(); }
public async Task TestGetData_NonGenericAsync() { ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestGetData_NonGenericAsync)); var key = Guid.NewGuid().ToString(); (int, int, int)data = (1, 2, 3); cache.SetData(key, data, TimeSpan.FromMilliseconds(100)); cache.GetData(key).Should().NotBeNull(); await Task.Delay(TimeSpan.FromMilliseconds(101)); cache.GetData(key).Should().BeNull(); }
public async Task TestGetData_GenericAsync() { ICacheInstance cache = MemoryCache.GetNamedInstance(Guid.NewGuid().ToString()); var key = Guid.NewGuid().ToString(); (int, int, int)data = (1, 2, 3); cache.SetData(key, data, TimeSpan.FromMilliseconds(100)); (int, int, int)dataRef = cache.GetData <(int, int, int)>(key); dataRef.Should().NotBeNull(); dataRef.Should().Be(data); await Task.Delay(TimeSpan.FromMilliseconds(200)); cache.GetData <(int, int, int)>(key).Should().Be(default);
public async Task TestCacheDelete_CollectionDataShouldBeDisposedAsync() { ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestCacheDelete_DataShouldBeDisposedAsync)); cache.CleanInternal = TimeSpan.FromSeconds(1); var data = new DummyDisposable(); var key = Guid.NewGuid().ToString(); cache.SetData(key, new[] { data }, TimeSpan.MaxValue); cache.TryDeleteKey(key).Should().BeTrue(); data.IsDisposed.Should().Be(false); await Task.Delay(cache.CleanInternal.Add(TimeSpan.FromMilliseconds(500))); cache.CleanIfNeeded(); data.IsDisposed.Should().Be(true); }
public async Task TestCacheDelete_LazyCollectionDataShouldBeDisposedAsync() { ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestCacheDelete_LazyDataShouldBeDisposedAsync)); cache.CleanInternal = TimeSpan.FromSeconds(1); var data = LazyUtils.ToLazy(() => new[] { new DummyDisposable() }); var key = Guid.NewGuid().ToString(); cache.SetData(key, data, TimeSpan.MaxValue); Console.WriteLine(data.Value.GetHashCode()); cache.TryDeleteKey(key).Should().BeTrue(); data.Value.ForEach(_ => _.IsDisposed.Should().Be(false)); await Task.Delay(cache.CleanInternal.Add(TimeSpan.FromMilliseconds(500))); cache.CleanIfNeeded(); data.Value.ForEach(_ => _.IsDisposed.Should().Be(true)); }
public async Task TestDeleteKey_DisposableAsync() { ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestDeleteKey_DisposableAsync)); cache.CleanInternal = TimeSpan.FromMilliseconds(200); var key = Guid.NewGuid().ToString(); var data = new DummyDisposable(); cache.SetData(key, data, TimeSpan.MaxValue); data.IsDisposed.Should().BeFalse(); cache.TryDeleteKey(key).Should().BeTrue(); cache.TryDeleteKey(key).Should().BeFalse(); data.IsDisposed.Should().BeFalse(); await Task.Delay(TimeSpan.FromMilliseconds(300)); data.IsDisposed.Should().BeTrue(); }
public static T GetAutoReloadDataWithInterval <T>( this ICacheInstance cache, string key, Func <T> dataFactory, TimeSpan timeToLive, TimeSpan dataReloadInternal, bool shouldReloadInBackground = true) { return(cache.GetAutoReloadDataWithCache <T>( key: key, dataFactory: dataFactory, eTagFactory: null, timeToLive: timeToLive, dataUpdateDetectInternal: dataReloadInternal, eTag: out _, shouldReloadInBackground: shouldReloadInBackground)); }
public async Task TestClearAsync() { ICacheInstance cache = MemoryCache.GetNamedInstance(Guid.NewGuid().ToString()); cache.CleanInternal = TimeSpan.FromMilliseconds(200); var key = Guid.NewGuid().ToString(); var data = new DummyDisposable(); cache.SetData(key, data, TimeSpan.MaxValue); cache.Size.Should().Be(1); data.IsDisposed.Should().BeFalse(); cache.Clear(); cache.Size.Should().Be(0); data.IsDisposed.Should().BeFalse(); await Task.Delay(TimeSpan.FromMilliseconds(300)); cache.CleanIfNeeded(); data.IsDisposed.Should().BeTrue(); }
public void TestCreateDeleteInstance() { var cacheName = Guid.NewGuid().ToString(); ICacheInstance cache = MemoryCache.GetNamedInstance(cacheName); cache.Should().NotBeNull(); var data = new DummyDisposable(); cache.SetData(nameof(data), data, Timeout.InfiniteTimeSpan); MemoryCache.GetNamedInstance(cacheName).Should().Be(cache); data.IsDisposed.Should().BeFalse(); MemoryCache.TryDeleteNamedInstance(cacheName).Should().BeTrue(); data.IsDisposed.Should().BeTrue(); MemoryCache.GetNamedInstance(cacheName).Should().NotBe(cache); }
public void TestGetData_Generic_InvalidCast() { ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestGetData_Generic_InvalidCast)); var key = Guid.NewGuid().ToString(); (int, int, int)data = (1, 2, 3); cache.SetData(key, data, TimeSpan.MaxValue); (int, int, int)dataRef = cache.GetData <(int, int, int)>(key); dataRef.Should().NotBeNull(); dataRef.Should().Be(data); var dataRefInvalid = cache.GetData <string>(key); dataRefInvalid.Should().Be(default(string)); dataRef = cache.GetData <(int, int, int)>(key); dataRef.Should().NotBeNull(); dataRef.Should().Be(data); }
public async Task TestCacheCleanBehaviourAsync(bool shouldReloadInBackground) { var cacheName = $"{nameof(TestCacheCleanBehaviourAsync)}|{shouldReloadInBackground}"; ICacheInstance cache = MemoryCache.GetNamedInstance(cacheName); cache.CleanInternal = TimeSpan.FromMilliseconds(200); cache.Size.Should().Be(0); GetOrCreate(cache, Guid.NewGuid().ToString(), TimeSpan.FromMilliseconds(200), shouldReloadInBackground: shouldReloadInBackground); cache.Size.Should().Be(1); GetOrCreate(cache, Guid.NewGuid().ToString(), TimeSpan.FromMilliseconds(500), shouldReloadInBackground: shouldReloadInBackground); cache.Size.Should().Be(2); await Task.Delay(TimeSpan.FromMilliseconds(100)); cache.Size.Should().Be(2); await Task.Delay(TimeSpan.FromMilliseconds(1000)); cache.Size.Should().Be(0); MemoryCache.TryDeleteNamedInstance(cacheName).Should().BeTrue(); }
public static T GetAutoReloadDataWithCache <T>( this ICacheInstance cache, string key, Func <Task <T> > dataFactory, Func <Task <string> > eTagFactory, TimeSpan timeToLive, TimeSpan dataUpdateDetectInternal, out string eTag, bool shouldReloadInBackground = true) { Func <T> df = () => dataFactory().ConfigureAwait(false).GetAwaiter().GetResult(); Func <string> ef = () => eTagFactory?.Invoke().ConfigureAwait(false).GetAwaiter().GetResult(); return(cache.GetAutoReloadDataWithCache <T>( key: key, dataFactory: df, eTagFactory: ef, timeToLive: timeToLive, dataUpdateDetectInternal: dataUpdateDetectInternal, eTag: out eTag, shouldReloadInBackground: shouldReloadInBackground)); }
public void TestCacheFuntionConcurrencyPerf(int numberOfConcurrentTasks, bool shouldReloadInBackground) { var key = Guid.NewGuid().ToString(); ICacheInstance cache = MemoryCache.GetNamedInstance(nameof(TestCacheFuntionConcurrency)); var counter = 0; Parallel.For(0, numberOfConcurrentTasks, i => { cache.GetAutoReloadDataWithInterval( key, async() => { await Task.Delay(500).ConfigureAwait(false); Interlocked.Increment(ref counter); return(i); }, TimeSpan.FromDays(1), TimeSpan.FromHours(1), shouldReloadInBackground: shouldReloadInBackground); }); counter.Should().Be(1); }
private static void GetOrCreate(ICacheInstance cache, string key, TimeSpan timeToLive, bool shouldReloadInBackground) { cache.GetAutoReloadDataWithInterval(key, () => new object(), timeToLive, TimeSpan.MaxValue, shouldReloadInBackground: shouldReloadInBackground); }
private static object GetOrCreate(ICacheInstance cache, string key, TimeSpan dataReloadInterval, bool shouldReloadInBackground) { return(cache.GetAutoReloadDataWithInterval(key, () => new object(), TimeSpan.MaxValue, dataReloadInterval, shouldReloadInBackground: shouldReloadInBackground)); }
public Get() { memoryCache = new MemoryCache(new MemoryCacheOptions()); instance = new CacheInstance(memoryCache, new CacheSettings(cacheDurationInSeconds: 45)); }
public UpdateSettings() { instance = new CacheInstance(new MemoryCache(new MemoryCacheOptions()), new CacheSettings(cacheDurationInSeconds: 45)); }
public async Task HttpGetETagCacheTestsAsync() { ICacheInstance cache = MemoryCache.GetNamedInstance(Guid.NewGuid().ToString()); using (var client = new HttpClient()) { var baseUrl = $"https://httpbin.org/etag/"; var etag = Guid.NewGuid(); int counter1 = 0; int counter2 = 0; var lazyResponse = LazyUtils.ToLazy(async() => { Interlocked.Increment(ref counter1); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}{etag}"); return(await client.SendAsync(request).ConfigureAwait(false)); }); cache.GetAutoReloadDataWithCache( baseUrl, async() => { Interlocked.Increment(ref counter2); return(await lazyResponse.Value.Content.ReadAsStringAsync().ConfigureAwait(false)); }, () => Task.FromResult(lazyResponse.Value.Headers.ETag?.Tag), TimeSpan.FromHours(1), TimeSpan.FromMilliseconds(100)); counter1.Should().Be(1); counter2.Should().Be(1); lazyResponse = LazyUtils.ToLazy(async() => { Interlocked.Increment(ref counter1); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}{etag}"); return(await client.SendAsync(request).ConfigureAwait(false)); }); cache.GetAutoReloadDataWithCache( baseUrl, async() => { Interlocked.Increment(ref counter2); return(await lazyResponse.Value.Content.ReadAsStringAsync().ConfigureAwait(false)); }, () => Task.FromResult(lazyResponse.Value.Headers.ETag?.Tag), TimeSpan.FromHours(1), TimeSpan.FromMilliseconds(100)); counter1.Should().Be(1); counter2.Should().Be(1); await Task.Delay(150); lazyResponse = LazyUtils.ToLazy(async() => { Interlocked.Increment(ref counter1); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}{etag}"); return(await client.SendAsync(request).ConfigureAwait(false)); }); cache.GetAutoReloadDataWithCache( baseUrl, async() => { Interlocked.Increment(ref counter2); return(await lazyResponse.Value.Content.ReadAsStringAsync().ConfigureAwait(false)); }, () => Task.FromResult(lazyResponse.Value.Headers.ETag?.Tag), TimeSpan.FromHours(1), TimeSpan.FromMilliseconds(100)); counter1.Should().Be(1); counter2.Should().Be(1); etag = Guid.NewGuid(); await Task.Delay(50); lazyResponse = LazyUtils.ToLazy(async() => { Interlocked.Increment(ref counter1); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}{etag}"); return(await client.SendAsync(request).ConfigureAwait(false)); }); cache.GetAutoReloadDataWithCache( baseUrl, async() => { Interlocked.Increment(ref counter2); return(await lazyResponse.Value.Content.ReadAsStringAsync().ConfigureAwait(false)); }, () => Task.FromResult(lazyResponse.Value.Headers.ETag?.Tag), TimeSpan.FromHours(1), TimeSpan.FromMilliseconds(100)); counter1.Should().Be(2); counter2.Should().Be(1); await Task.Delay(150); lazyResponse = LazyUtils.ToLazy(async() => { Interlocked.Increment(ref counter1); var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}{etag}"); return(await client.SendAsync(request).ConfigureAwait(false)); }); cache.GetAutoReloadDataWithCache( baseUrl, async() => { Interlocked.Increment(ref counter2); return(await lazyResponse.Value.Content.ReadAsStringAsync().ConfigureAwait(false)); }, () => Task.FromResult(lazyResponse.Value.Headers.ETag?.Tag), TimeSpan.FromHours(1), TimeSpan.FromMilliseconds(100)); counter1.Should().Be(3); counter2.Should().Be(2); } }