public async Task Should_execute_delegate_and_put_value_in_cache_if_cache_does_not_hold_value() { const string valueToReturn = "valueToReturn"; const string executionKey = "SomeExecutionKey"; IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); CachePolicy cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); ((string)await stubCacheProvider.GetAsync(executionKey, CancellationToken.None, false).ConfigureAwait(false)).Should().BeNull(); (await cache.ExecuteAsync(async() => { await TaskHelper.EmptyTask.ConfigureAwait(false); return(valueToReturn); }, new Context(executionKey)).ConfigureAwait(false)).Should().Be(valueToReturn); ((string)await stubCacheProvider.GetAsync(executionKey, CancellationToken.None, false).ConfigureAwait(false)).Should().Be(valueToReturn); }
public async Task Should_execute_delegate_but_not_put_value_in_cache_if_cache_does_not_hold_value_but_ttl_indicates_not_worth_caching() { const string valueToReturn = "valueToReturn"; const string operationKey = "SomeOperationKey"; IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); CachePolicy cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.Zero); ((string)await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false).ConfigureAwait(false)).Should().Be(null); (await cache.ExecuteAsync(async ctx => { await TaskHelper.EmptyTask.ConfigureAwait(false); return(valueToReturn); }, new Context(operationKey)).ConfigureAwait(false)).Should().Be(valueToReturn); ((string)await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false).ConfigureAwait(false)).Should().Be(null); }
public async Task Should_allow_custom_ICacheKeyStrategy() { Action <Context, string, Exception> noErrorHandling = (_, __, ___) => { }; Action <Context, string> emptyDelegate = (_, __) => { }; IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); ICacheKeyStrategy cacheKeyStrategy = new StubCacheKeyStrategy(context => context.ExecutionKey + context["id"]); CachePolicy cache = Policy.CacheAsync(stubCacheProvider, new RelativeTtl(TimeSpan.MaxValue), cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, noErrorHandling, noErrorHandling); object person1 = new object(); await stubCacheProvider.PutAsync("person1", person1, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false).ConfigureAwait(false); object person2 = new object(); await stubCacheProvider.PutAsync("person2", person2, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false).ConfigureAwait(false); bool funcExecuted = false; Func <Task <object> > func = async() => { funcExecuted = true; await TaskHelper.EmptyTask.ConfigureAwait(false); return(new object()); }; (await cache.ExecuteAsync(func, new Context("person", new { id = "1" }.AsDictionary())).ConfigureAwait(false)).Should().BeSameAs(person1); funcExecuted.Should().BeFalse(); (await cache.ExecuteAsync(func, new Context("person", new { id = "2" }.AsDictionary())).ConfigureAwait(false)).Should().BeSameAs(person2); funcExecuted.Should().BeFalse(); }
private async Task <AccessTokenResponse> _getToken <TRequest>(TRequest request) { var key = (string)_getKey((dynamic)request); var task = _pendingTasks.GetOrAdd( key, k => _accessTokenResponseCachePolicy.ExecuteAsync( ctx => _inner.GetTokenAsync((dynamic)request), new Context(k) ) ) as Task <AccessTokenResponse>; var res = await task; _pendingTasks.TryRemove(key, out var _); return(res); }
public async Task <IActionResult> Get(int id) { string requestEndpoint = $"inventory/{id}"; Context policyExecutionContext = new Context($"GetInventoryById-{id}"); HttpResponseMessage response = await _cachePolicy.ExecuteAsync( () => _httpClient.GetAsync(requestEndpoint), policyExecutionContext); if (response.IsSuccessStatusCode) { int itemsInStock = JsonConvert.DeserializeObject <int>(await response.Content.ReadAsStringAsync()); return(Ok(itemsInStock)); } return(StatusCode((int)response.StatusCode, response.Content.ReadAsStringAsync())); }
public async Task Should_execute_delegate_and_put_value_in_cache_for_non_nullable_types_if_cache_does_not_hold_value() { const ResultPrimitive valueToReturn = ResultPrimitive.Substitute; const string operationKey = "SomeOperationKey"; IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); CachePolicy cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); (await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false)).Should().BeNull(); (await cache.ExecuteAsync(async ctx => { await TaskHelper.EmptyTask.ConfigureAwait(false); return(ResultPrimitive.Substitute); }, new Context(operationKey))).Should().Be(valueToReturn); (await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false)).Should().Be(valueToReturn); }
public async Task Should_not_error_for_executions_on_non_nullable_types_if_cache_does_not_hold_value() { const string operationKey = "SomeOperationKey"; bool onErrorCalled = false; Action <Context, string, Exception> onError = (ctx, key, exc) => { onErrorCalled = true; }; IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); CachePolicy cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue, onError); (await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false)).Should().BeNull(); ResultPrimitive result = await cache.ExecuteAsync(async ctx => { await TaskHelper.EmptyTask.ConfigureAwait(false); return(ResultPrimitive.Substitute); }, new Context(operationKey)); onErrorCalled.Should().BeFalse(); }
public async Task Should_not_execute_oncachemiss_if_dont_query_cache_because_cache_key_not_set() { string valueToReturn = Guid.NewGuid().ToString(); Action <Context, string, Exception> noErrorHandling = (_, __, ___) => { }; Action <Context, string> emptyDelegate = (_, __) => { }; bool onCacheMissExecuted = false; Action <Context, string> onCacheMiss = (ctx, key) => { onCacheMissExecuted = true; }; CachePolicy cache = Policy.CacheAsync(new StubCacheProvider(), new RelativeTtl(TimeSpan.MaxValue), DefaultCacheKeyStrategy.Instance, emptyDelegate, onCacheMiss, emptyDelegate, noErrorHandling, noErrorHandling); (await cache.ExecuteAsync(async() => { await TaskHelper.EmptyTask.ConfigureAwait(false); return(valueToReturn); } /*, no execution key */).ConfigureAwait(false)) .Should().Be(valueToReturn); onCacheMissExecuted.Should().BeFalse(); }
public async Task Should_return_value_from_cache_and_not_execute_delegate_if_cache_holds_value() { const string valueToReturnFromCache = "valueToReturnFromCache"; const string valueToReturnFromExecution = "valueToReturnFromExecution"; const string executionKey = "SomeExecutionKey"; IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); CachePolicy cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue); await stubCacheProvider.PutAsync(executionKey, valueToReturnFromCache, new Ttl(TimeSpan.MaxValue), CancellationToken.None, false).ConfigureAwait(false); bool delegateExecuted = false; (await cache.ExecuteAsync(async() => { delegateExecuted = true; await TaskHelper.EmptyTask.ConfigureAwait(false); return(valueToReturnFromExecution); }, new Context(executionKey)) .ConfigureAwait(false)) .Should().Be(valueToReturnFromCache); delegateExecuted.Should().BeFalse(); }
public async Task Should_call_onError_delegate_if_cache_put_errors() { Exception ex = new Exception(); IAsyncCacheProvider stubCacheProvider = new StubErroringCacheProvider(getException: null, putException: ex); Exception exceptionFromCacheProvider = null; const string valueToReturn = "valueToReturn"; const string executionKey = "SomeExecutionKey"; Action <Context, string, Exception> onError = (ctx, key, exc) => { exceptionFromCacheProvider = exc; }; CachePolicy cache = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue, onError); ((string)await stubCacheProvider.GetAsync(executionKey, CancellationToken.None, false).ConfigureAwait(false)).Should().BeNull(); (await cache.ExecuteAsync(async() => { await TaskHelper.EmptyTask.ConfigureAwait(false); return(valueToReturn); }, new Context(executionKey)).ConfigureAwait(false)).Should().Be(valueToReturn); // error should be captured by onError delegate. exceptionFromCacheProvider.Should().Be(ex); // failed to put it in the cache ((string)await stubCacheProvider.GetAsync(executionKey, CancellationToken.None, false).ConfigureAwait(false)).Should().BeNull(); }