public async Task DataInMemoryCacheButNotFresh_BackendGetErrors() { CachedItemWrapper <string> memoryCacheItem = new CachedItemWrapper <string>("fromMemCache", new DateTimeOffset(2020, 05, 17, 19, 59, 59, 00, new TimeSpan(0, 0, 0))); _pollySyncCacheProvider.Setup(x => x.TryGet(It.IsAny <string>())).Returns((true, memoryCacheItem)); _mockableDateTime.Setup(x => x.UtcNow).Returns(new DateTimeOffset(2020, 05, 17, 20, 00, 00, 00, new TimeSpan(0, 0, 0))); Func <CancellationToken, Task <string> > _dataGetterDelegate1 = (token) => { _numberOfTimesDataGetterDelegate1Called++; throw new Exception("An error"); }; MemCacheFactory <string> memCacheFactory = new MemCacheFactory <string>(_pollySyncCacheProvider.Object, _mockableDateTime.Object, _logger.Object); IMemDistCache <string> memCache = memCacheFactory.GetCache(_defaultCacheDuration, ResetTimeFactory.OnHour); string result = await memCache.GetCachedDataAsync(_dataGetterDelegate1, _key, RefreshBehaviour.DontWaitForFreshData, CancellationToken.None); Assert.AreEqual("fromMemCache", result); _pollySyncCacheProvider.Verify(x => x.TryGet(It.Is <string>(y => y == _key)), Times.Once); await Task.Delay(_waitForBackgroundThreadToCompleteMs); // wait for background thread _logger.Verify(x => x.LogError(It.Is <string>(y => y == $"Error executing data getter for key: {_key}"), It.IsAny <Exception>())); Assert.AreEqual(1, _numberOfTimesDataGetterDelegate1Called); DateTimeOffset whenDataWillNotBeFresh = new DateTimeOffset(2020, 05, 17, 21, 00, 00, 00, new TimeSpan(0, 0, 0)); _pollySyncCacheProvider.Verify(x => x.Put(It.IsAny <string>(), It.Is <CachedItemWrapper <string> >(y => y.Content == "dataFromBackendGet" && y.IsFreshUntil == whenDataWillNotBeFresh), It.Is <Ttl>(y => y.Timespan == _defaultCacheDuration)), Times.Never); }
public async Task DataInMemoryCacheButNotFresh_DontRefreshData() { CachedItemWrapper <string> memoryCacheItem = new CachedItemWrapper <string>("fromMemCache", new DateTimeOffset(2020, 05, 17, 19, 59, 59, 00, new TimeSpan(0, 0, 0))); _pollySyncCacheProvider.Setup(x => x.TryGet(It.IsAny <string>())).Returns((true, memoryCacheItem)); _mockableDateTime.Setup(x => x.UtcNow).Returns(new DateTimeOffset(2020, 05, 17, 20, 00, 00, 00, new TimeSpan(0, 0, 0))); MemCacheFactory <string> memCacheFactory = new MemCacheFactory <string>(_pollySyncCacheProvider.Object, _mockableDateTime.Object, _logger.Object); IMemDistCache <string> memCache = memCacheFactory.GetCache(_defaultCacheDuration, ResetTimeFactory.OnHour); string result = await memCache.GetCachedDataAsync(_dataGetterDelegate1, _key, RefreshBehaviour.DontRefreshData, CancellationToken.None); Assert.AreEqual("fromMemCache", result); _pollySyncCacheProvider.Verify(x => x.TryGet(It.Is <string>(y => y == _key)), Times.Once); await Task.Delay(_waitForBackgroundThreadToCompleteMs); // wait for background thread Assert.AreEqual(0, _numberOfTimesDataGetterDelegate1Called); _pollySyncCacheProvider.Verify(x => x.Put(It.IsAny <string>(), It.IsAny <CachedItemWrapper <string> >(), It.Is <Ttl>(y => y.Timespan == _defaultCacheDuration)), Times.Never); }
public async Task DataNotInMemoryCache_DataInDistCacheNotFresh_WaitForFreshData() { CachedItemWrapper <string> distCacheItem = new CachedItemWrapper <string>("fromDistCache", new DateTimeOffset(2020, 05, 17, 19, 59, 59, 00, new TimeSpan(0, 0, 0))); _pollySyncCacheProvider.Setup(x => x.TryGet(It.IsAny <string>())).Returns((false, null)); _distributedCacheWrapper.Setup(x => x.TryGetAsync <CachedItemWrapper <string> >(It.IsAny <string>(), It.IsAny <CancellationToken>(), It.IsAny <bool>())).ReturnsAsync((true, distCacheItem)); _mockableDateTime.Setup(x => x.UtcNow).Returns(new DateTimeOffset(2020, 05, 17, 20, 00, 00, 00, new TimeSpan(0, 0, 0))); MemDistCacheFactory <string> memDistCacheFactory = new MemDistCacheFactory <string>(_pollySyncCacheProvider.Object, _distributedCacheWrapper.Object, _mockableDateTime.Object, _logger.Object); IMemDistCache <string> memDistCache = memDistCacheFactory.GetCache(_defaultCacheDuration, Cache.ResetTimeFactory.OnHour); string result = await memDistCache.GetCachedDataAsync(_dataGetterDelegate1, _key, RefreshBehaviour.WaitForFreshData, CancellationToken.None); Assert.AreEqual("dataFromBackendGet", result); _pollySyncCacheProvider.Verify(x => x.TryGet(It.Is <string>(y => y == _key)), Times.Once); _distributedCacheWrapper.Verify(x => x.TryGetAsync <CachedItemWrapper <string> >(It.Is <string>(y => y == _key), It.IsAny <CancellationToken>(), It.IsAny <bool>()), Times.Once); Assert.AreEqual(1, _numberOfTimesDataGetterDelegate1Called); DateTimeOffset whenDataWillNotBeFresh = new DateTimeOffset(2020, 05, 17, 21, 00, 00, 00, new TimeSpan(0, 0, 0)); _pollySyncCacheProvider.Verify(x => x.Put(It.Is <string>(y => y == _key), It.Is <CachedItemWrapper <string> >(y => y.Content == "dataFromBackendGet" && y.IsFreshUntil == whenDataWillNotBeFresh), It.Is <Ttl>(y => y.Timespan == _defaultCacheDuration)), Times.Once); _distributedCacheWrapper.Verify(x => x.PutAsync(It.Is <string>(y => y == _key), It.Is <CachedItemWrapper <string> >(y => y.Content == "dataFromBackendGet" && y.IsFreshUntil == whenDataWillNotBeFresh), It.Is <Ttl>(y => y.Timespan == _defaultCacheDuration), It.IsAny <CancellationToken>(), It.IsAny <bool>()), Times.Once); }
/// <inheritdoc />> public async Task <T> GetCachedDataAsync(Func <CancellationToken, Task <T> > dataGetter, string key, RefreshBehaviour refreshBehaviour, CancellationToken cancellationToken, NotInCacheBehaviour notInCacheBehaviour) { (bool, object)memoryWrappedResult = _pollySyncCacheProvider.TryGet(key); bool isObjectInMemoryCache = memoryWrappedResult.Item1; if (isObjectInMemoryCache) { CachedItemWrapper <T> memoryResultObject = (CachedItemWrapper <T>)memoryWrappedResult.Item2; bool isMemoryCacheFresh = IsFresh(memoryResultObject); if (!isMemoryCacheFresh) { if (refreshBehaviour == RefreshBehaviour.WaitForFreshData) { return(await _collapserPolicy.ExecuteAsync(async() => await RecacheItemInMemoryCacheAsync(dataGetter, key, cancellationToken, _whenDataIsStaleDelegate))); } else if (refreshBehaviour == RefreshBehaviour.DontWaitForFreshData) { #pragma warning disable 4014 Task.Factory.StartNew(async() => await RecacheItemInMemoryCacheAsync(dataGetter, key, cancellationToken, _whenDataIsStaleDelegate), cancellationToken); #pragma warning restore 4014 } } return(memoryResultObject.Content); } if (notInCacheBehaviour == NotInCacheBehaviour.WaitForData) { return(await RecacheItemInMemoryCacheAsync(dataGetter, key, cancellationToken, _whenDataIsStaleDelegate)); } else if (notInCacheBehaviour == NotInCacheBehaviour.DontWaitForData) { #pragma warning disable 4014 Task.Factory.StartNew(async() => await RecacheItemInMemoryCacheAsync(dataGetter, key, cancellationToken, _whenDataIsStaleDelegate), cancellationToken); #pragma warning restore 4014 } return(default);
public async Task DataInMemoryCacheAndFresh() { CachedItemWrapper <string> memoryCacheItem = new CachedItemWrapper <string>("fromMemDistCache", new DateTimeOffset(2020, 05, 17, 20, 00, 00, 00, new TimeSpan(0, 0, 0))); _pollySyncCacheProvider.Setup(x => x.TryGet(It.IsAny <string>())).Returns((true, memoryCacheItem)); _mockableDateTime.Setup(x => x.UtcNow).Returns(new DateTimeOffset(2020, 05, 17, 20, 00, 00, 00, new TimeSpan(0, 0, 0))); MemDistCacheFactory <string> memDistCacheFactory = new MemDistCacheFactory <string>(_pollySyncCacheProvider.Object, _distributedCacheWrapper.Object, _mockableDateTime.Object, _logger.Object); IMemDistCache <string> memDistCache = memDistCacheFactory.GetCache(_defaultCacheDuration, Cache.ResetTimeFactory.OnHour); string result = await memDistCache.GetCachedDataAsync(_dataGetterDelegate1, _key, RefreshBehaviour.DontWaitForFreshData, CancellationToken.None); Assert.AreEqual("fromMemDistCache", result); Assert.AreEqual(0, _numberOfTimesDataGetterDelegate1Called); _pollySyncCacheProvider.Verify(x => x.TryGet(It.Is <string>(y => y == _key)), Times.Once); _pollySyncCacheProvider.Verify(x => x.Put(It.IsAny <string>(), It.IsAny <CachedItemWrapper <string> >(), It.IsAny <Ttl>()), Times.Never); _distributedCacheWrapper.Verify(x => x.TryGetAsync <string>(It.IsAny <string>(), It.IsAny <CancellationToken>(), It.IsAny <bool>()), Times.Never); _distributedCacheWrapper.Verify(x => x.PutAsync(It.IsAny <string>(), It.IsAny <CachedItemWrapper <string> >(), It.IsAny <Ttl>(), It.IsAny <CancellationToken>(), It.IsAny <bool>()), Times.Never); }