public async Task GetAsync_should_return_false_on_unknown_key() { Mock <IDistributedCache> mockDistributedCache = new Mock <IDistributedCache>(); string key = "anything"; var cachedValue = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); mockDistributedCache.Setup(idc => idc.GetAsync(It.Is <string>(k => k == key) #if NETCOREAPP2_0 , It.IsAny <CancellationToken>() #endif )).Returns(Task.FromResult(cachedValue)); mockDistributedCache.Setup(idc => idc.GetAsync(It.Is <string>(k => k != key) #if NETCOREAPP2_0 , It.IsAny <CancellationToken>() #endif )).Returns(Task.FromResult <byte[]>(null)).Verifiable(); IAsyncCacheProvider <byte[]> provider = mockDistributedCache.Object.AsAsyncCacheProvider <byte[]>(); string someOtherKey = Guid.NewGuid().ToString(); (bool got, byte[] fromCache) = await provider.TryGetAsync(someOtherKey, CancellationToken.None, false); got.Should().BeFalse(); mockDistributedCache.Verify(v => v.GetAsync(someOtherKey #if NETCOREAPP2_0 , It.IsAny <CancellationToken>() #endif ), Times.Once); fromCache.Should().BeNull(); }
public void GetAsync_should_throw_for_cancellation() { Mock <IDistributedCache> mockDistributedCache = new Mock <IDistributedCache>(); string key = "anything"; IAsyncCacheProvider <byte[]> provider = mockDistributedCache.Object.AsAsyncCacheProvider <byte[]>(); Func <Task> action = () => provider.TryGetAsync(key, new CancellationToken(true), false); action.ShouldThrow <OperationCanceledException>(); }
public async Task GetAsync_should_return_instance_previously_stored_in_cache() { Mock <IDistributedCache> mockDistributedCache = new Mock <IDistributedCache>(); string key = "anything"; var cachedValue = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()); mockDistributedCache.Setup(idc => idc.GetAsync(It.Is <string>(k => k == key) #if NETCOREAPP2_0 , It.IsAny <CancellationToken>() #endif )).Returns(Task.FromResult(cachedValue)); IAsyncCacheProvider <byte[]> provider = mockDistributedCache.Object.AsAsyncCacheProvider <byte[]>(); (bool got, byte[] fromCache) = await provider.TryGetAsync(key, CancellationToken.None, false); got.Should().BeTrue(); mockDistributedCache.Verify(v => v.GetAsync(key #if NETCOREAPP2_0 , It.IsAny <CancellationToken>() #endif ), Times.Once); fromCache.Should().BeSameAs(cachedValue); }
public async Task GetAsync_should_return_instance_previously_stored_in_cache() { Mock <IDistributedCache> mockDistributedCache = new Mock <IDistributedCache>(); string key = "anything"; string valueToCache = Guid.NewGuid().ToString(); mockDistributedCache.Setup(idc => idc.GetAsync(It.Is <string>(k => k == key) #if !NETCOREAPP1_1 , It.IsAny <CancellationToken>() #endif )).Returns(Task.FromResult(Encoding.UTF8.GetBytes(valueToCache))).Verifiable(); // Because GetStringAsync() is an extension method, we cannot mock it. We mock GetAsync() instead. IAsyncCacheProvider <string> provider = mockDistributedCache.Object.AsAsyncCacheProvider <string>(); (bool got, string fromCache) = await provider.TryGetAsync(key, CancellationToken.None, false); got.Should().BeTrue(); mockDistributedCache.Verify(v => v.GetAsync(key #if !NETCOREAPP1_1 , It.IsAny <CancellationToken>() #endif ), Times.Once); fromCache.Should().Be(valueToCache); }
/// <summary> /// Gets a value from the cache asynchronously. /// </summary> /// <param name="key">The cache key.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="continueOnCapturedContext">Whether async calls should continue on a captured synchronization context.</param> /// <returns> /// A <see cref="Task{TResult}" /> promising as Result a tuple whose first element is a value indicating whether /// the key was found in the cache, and whose second element is the value from the cache (null if not found). /// </returns> public async Task <(bool, object)> TryGetAsync(string key, CancellationToken cancellationToken, bool continueOnCapturedContext) { (bool cacheHit, TSerialized objectToDeserialize) = await _wrappedCacheProvider.TryGetAsync(key, cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext); return(cacheHit, cacheHit ? _serializer.Deserialize(objectToDeserialize) : null); }
internal static async Task <TResult> ImplementationAsync <TResult>( IAsyncCacheProvider <TResult> cacheProvider, ITtlStrategy <TResult> ttlStrategy, Func <Context, string> cacheKeyStrategy, Func <Context, CancellationToken, Task <TResult> > action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext, Action <Context, string> onCacheGet, Action <Context, string> onCacheMiss, Action <Context, string> onCachePut, Action <Context, string, Exception> onCacheGetError, Action <Context, string, Exception> onCachePutError) { cancellationToken.ThrowIfCancellationRequested(); string cacheKey = cacheKeyStrategy(context); if (cacheKey == null) { return(await action(context, cancellationToken).ConfigureAwait(continueOnCapturedContext)); } bool cacheHit; TResult valueFromCache; try { (cacheHit, valueFromCache) = await cacheProvider.TryGetAsync(cacheKey, cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext); } catch (Exception ex) { cacheHit = false; valueFromCache = default(TResult); onCacheGetError(context, cacheKey, ex); } if (cacheHit) { onCacheGet(context, cacheKey); return(valueFromCache); } else { onCacheMiss(context, cacheKey); } TResult result = await action(context, cancellationToken).ConfigureAwait(continueOnCapturedContext); Ttl ttl = ttlStrategy.GetTtl(context, result); if (ttl.Timespan > TimeSpan.Zero) { try { await cacheProvider.PutAsync(cacheKey, result, ttl, cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext); onCachePut(context, cacheKey); } catch (Exception ex) { onCachePutError(context, cacheKey, ex); } } return(result); }