public void Should_throw_when_ttl_strategy_is_null() { IAsyncCacheProvider cacheProvider = new StubCacheProvider(); ITtlStrategy ttlStrategy = null; Action action = () => Policy.CacheAsync(cacheProvider, ttlStrategy); action.ShouldThrow <ArgumentNullException>().And.ParamName.Should().Be("ttlStrategy"); }
/// <summary> /// <para>Builds an <see cref="AsyncPolicy" /> that will function like a result cache for delegate executions returning a result.</para> /// <para>Before executing a delegate returning a result, checks whether the <paramref name="cacheProvider" /> holds a value for the cache key. /// If the <paramref name="cacheProvider" /> provides a value, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider" /> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider" />, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="onCacheGet">Delegate to call on a cache hit, when value is returned from cache.</param> /// <param name="onCacheMiss">Delegate to call on a cache miss.</param> /// <param name="onCachePut">Delegate to call on cache put.</param> /// <param name="onCacheGetError">Delegate to call if an exception is thrown when attempting to get a value from the cache, passing the execution context, the cache key, and the exception.</param> /// <param name="onCachePutError">Delegate to call if an exception is thrown when attempting to put a value in the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> /// <exception cref="ArgumentNullException">onCacheGet</exception> /// <exception cref="ArgumentNullException">onCacheMiss</exception> /// <exception cref="ArgumentNullException">onCachePut</exception> /// <exception cref="ArgumentNullException">onCacheGetError</exception> /// <exception cref="ArgumentNullException">onCachePutError</exception> public static AsyncCachePolicy CacheAsync( IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action <Context, string> onCacheGet, Action <Context, string> onCacheMiss, Action <Context, string> onCachePut, Action <Context, string, Exception> onCacheGetError, Action <Context, string, Exception> onCachePutError) => CacheAsync(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError);
/// <summary> /// <para>Builds a <see cref="Policy"/> that will function like a result cache for delegate executions returning a result.</para> /// <para>Before executing a delegate returning a result, checks whether the <paramref name="cacheProvider"/> holds a value for the cache key determined by applying the <paramref name="cacheKeyStrategy"/> to the execution <see cref="Context"/>. /// If the <paramref name="cacheProvider"/> provides a value from cache, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider"/> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider"/>, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="cacheKeyStrategy">The cache key strategy.</param> /// <param name="onCacheGet">Delegate to call on a cache hit, when value is returned from cache.</param> /// <param name="onCacheMiss">Delegate to call on a cache miss.</param> /// <param name="onCachePut">Delegate to call on cache put.</param> /// <param name="onCacheGetError">Delegate to call if an exception is thrown when attempting to get a value from the cache, passing the execution context, the cache key, and the exception.</param> /// <param name="onCachePutError">Delegate to call if an exception is thrown when attempting to put a value in the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="System.ArgumentNullException"> /// </exception> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> /// <exception cref="ArgumentNullException">cacheKeyStrategy</exception> /// <exception cref="ArgumentNullException">onCacheGet</exception> /// <exception cref="ArgumentNullException">onCacheMiss</exception> /// <exception cref="ArgumentNullException">onCachePut</exception> /// <exception cref="ArgumentNullException">onCacheGetError</exception> /// <exception cref="ArgumentNullException">onCachePutError</exception> public static CachePolicy Cache( ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action <Context, string> onCacheGet, Action <Context, string> onCacheMiss, Action <Context, string> onCachePut, Action <Context, string, Exception> onCacheGetError, Action <Context, string, Exception> onCachePutError) => Cache(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError);
/// <summary> /// <para>Builds a <see cref="Policy" /> that will function like a result cache for delegate executions returning a <typeparamref name="TResult"/>.</para> /// <para>Before executing a delegate, checks whether the <paramref name="cacheProvider" /> holds a value for the cache key determined by applying the <paramref name="cacheKeyStrategy"/> to the execution <see cref="Context"/>. /// If the <paramref name="cacheProvider" /> contains a value, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider" /> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider" />, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="cacheKeyStrategy">The cache key strategy.</param> /// <param name="onCacheGet">Delegate to call on a cache hit, when value is returned from cache.</param> /// <param name="onCacheMiss">Delegate to call on a cache miss.</param> /// <param name="onCachePut">Delegate to call on cache put.</param> /// <param name="onCacheGetError">Delegate to call if an exception is thrown when attempting to get a value from the cache, passing the execution context, the cache key, and the exception.</param> /// <param name="onCachePutError">Delegate to call if an exception is thrown when attempting to put a value in the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> /// <exception cref="ArgumentNullException">cacheKeyStrategy</exception> /// <exception cref="ArgumentNullException">onCacheGet</exception> /// <exception cref="ArgumentNullException">onCacheMiss</exception> /// <exception cref="ArgumentNullException">onCachePut</exception> /// <exception cref="ArgumentNullException">onCacheGetError</exception> /// <exception cref="ArgumentNullException">onCachePutError</exception> public static CachePolicy <TResult> Cache <TResult>( ISyncCacheProvider <TResult> cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action <Context, string> onCacheGet, Action <Context, string> onCacheMiss, Action <Context, string> onCachePut, Action <Context, string, Exception> onCacheGetError, Action <Context, string, Exception> onCachePutError) { return(Cache <TResult>(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError)); }
/// <summary> /// Generates a Polly <see cref="CachePolicy{HttpResponseMessage}"/> from the configuration. /// </summary> /// <param name="logger">The <see cref="ILogger"/> instance to use for logging.</param> /// <returns>A <see cref="CachePolicy{HttpResponseMessage}"/> instance.</returns> /// <remarks> /// Currently only supports in-memory cache. /// Operation key set on the context is used as the cache key. /// </remarks> public IAsyncPolicy <HttpResponseMessage> AsTypeModel(ILogger logger) { _ = logger ?? throw new ArgumentNullException(nameof(logger)); if (Time is null || TimeSpan.Equals(Time.AsTimeSpan(), TimeSpan.Zero)) { logger.LogCritical("{PolicyConfig} : {Property} must be a valid time span", nameof(CacheConfig), "time"); throw new InvalidOperationException("time must be a valid time span"); } // Create delegates void OnCacheGet(Context context, string key) => logger.LogInformation("{PolicyKey} at {OperationKey}: Retrieving {Key} from cache", context.PolicyKey, context.OperationKey, key); void OnCacheMiss(Context context, string key) => logger.LogInformation("{PolicyKey} at {OperationKey}: {Key} was not present in cache", context.PolicyKey, context.OperationKey, key); void OnCachePut(Context context, string key) => logger.LogInformation("{PolicyKey} at {OperationKey}: Inserting {Key} into cache", context.PolicyKey, context.OperationKey, key); void OnCacheGetError(Context context, string key, Exception exception) => logger.LogError(exception, "{PolicyKey} at {OperationKey}: Error retrieving {Key} from cache", context.PolicyKey, context.OperationKey, key); void OnCachePutError(Context context, string key, Exception exception) => logger.LogError(exception, "{PolicyKey} at {OperationKey}: Error inserting {Key} into cache", context.PolicyKey, context.OperationKey, key); if (!Absolute) { // Cache strategy if it is purely time span based strategy = CreateStrategy(); } // Create policy with default cache key strategy var cache = Policy .CacheAsync(cacheProvider, ttlStrategy: new ResultTtl <HttpResponseMessage>(CacheOKResponse), onCacheGet: OnCacheGet, onCacheMiss: OnCacheMiss, onCachePut: OnCachePut, onCacheGetError: OnCacheGetError, onCachePutError: OnCachePutError); return(cache); }
public void Can_render_SlidingExpiration_as_ttlstrategy() { TimeSpan forwardTimeSpan = TimeSpan.FromDays(1); DistributedCacheEntryOptions entryOptions = new DistributedCacheEntryOptions() { SlidingExpiration = forwardTimeSpan }; ITtlStrategy ttlStrategy = entryOptions.AsTtlStrategy(); ttlStrategy.Should().BeOfType <SlidingTtl>(); Ttl ttl = ttlStrategy.GetTtl(noContext, null); ttl.SlidingExpiration.Should().BeTrue(); ttl.Timespan.Should().BeCloseTo(forwardTimeSpan); }
public void Can_render_AbsoluteExpirationRelativeToNow_as_ttlstrategy() { TimeSpan forwardTimeSpan = TimeSpan.FromDays(1); DistributedCacheEntryOptions entryOptions = new DistributedCacheEntryOptions() { AbsoluteExpirationRelativeToNow = forwardTimeSpan }; ITtlStrategy ttlStrategy = entryOptions.AsTtlStrategy(); ttlStrategy.Should().BeOfType <RelativeTtl>(); Ttl ttl = ttlStrategy.GetTtl(noContext, null); ttl.SlidingExpiration.Should().BeFalse(); ttl.Timespan.Should().BeCloseTo(forwardTimeSpan, 10000); }
/// <summary> /// <para>Builds a <see cref="Policy" /> that will function like a result cache for delegate executions returning a <typeparamref name="TResult"/>.</para> /// <para>Before executing a delegate, checks whether the <paramref name="cacheProvider" /> holds a value for the cache key determined by applying the <paramref name="cacheKeyStrategy"/> to the execution <see cref="Context"/>. /// If the <paramref name="cacheProvider" /> contains a value, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider" /> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider" />, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="cacheKeyStrategy">The cache key strategy.</param> /// <param name="onCacheGet">Delegate to call on a cache hit, when value is returned from cache.</param> /// <param name="onCacheMiss">Delegate to call on a cache miss.</param> /// <param name="onCachePut">Delegate to call on cache put.</param> /// <param name="onCacheGetError">Delegate to call if an exception is thrown when attempting to get a value from the cache, passing the execution context, the cache key, and the exception.</param> /// <param name="onCachePutError">Delegate to call if an exception is thrown when attempting to put a value in the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> /// <exception cref="ArgumentNullException">cacheKeyStrategy</exception> /// <exception cref="ArgumentNullException">onCacheGet</exception> /// <exception cref="ArgumentNullException">onCacheMiss</exception> /// <exception cref="ArgumentNullException">onCachePut</exception> /// <exception cref="ArgumentNullException">onCacheGetError</exception> /// <exception cref="ArgumentNullException">onCachePutError</exception> public static CachePolicy <TResult> Cache <TResult>( ISyncCacheProvider <TResult> cacheProvider, ITtlStrategy ttlStrategy, Func <Context, string> cacheKeyStrategy, Action <Context, string> onCacheGet, Action <Context, string> onCacheMiss, Action <Context, string> onCachePut, Action <Context, string, Exception> onCacheGetError, Action <Context, string, Exception> onCachePutError) { if (cacheProvider == null) { throw new ArgumentNullException(nameof(cacheProvider)); } if (ttlStrategy == null) { throw new ArgumentNullException(nameof(ttlStrategy)); } if (cacheKeyStrategy == null) { throw new ArgumentNullException(nameof(cacheKeyStrategy)); } if (onCacheGet == null) { throw new ArgumentNullException(nameof(onCacheGet)); } if (onCacheMiss == null) { throw new ArgumentNullException(nameof(onCacheMiss)); } if (onCachePut == null) { throw new ArgumentNullException(nameof(onCachePut)); } if (onCachePutError == null) { throw new ArgumentNullException(nameof(onCachePutError)); } if (onCachePutError == null) { throw new ArgumentNullException(nameof(onCachePutError)); } return(new CachePolicy <TResult>(cacheProvider, ttlStrategy, cacheKeyStrategy, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError)); }
public void Can_render_AbsoluteExpiration_as_ttlstrategy() { TimeSpan forwardTimeSpan = TimeSpan.FromDays(1); DateTime date = DateTime.Now.Add(forwardTimeSpan); DistributedCacheEntryOptions entryOptions = new DistributedCacheEntryOptions() { AbsoluteExpiration = date }; ITtlStrategy ttlStrategy = entryOptions.AsTtlStrategy(); ttlStrategy.Should().BeOfType <AbsoluteTtl>(); Ttl ttl = ttlStrategy.GetTtl(noContext); ttl.SlidingExpiration.Should().BeFalse(); ttl.Timespan.Should().BeCloseTo(forwardTimeSpan, 10000); }
/// <summary> /// <para>Builds a <see cref="Policy" /> that will function like a result cache for delegate executions returning a result.</para> /// <para>Before executing a delegate returning a result, checks whether the <paramref name="cacheProvider" /> holds a value for the cache key determined by applying the <paramref name="cacheKeyStrategy"/> to the execution <see cref="Context"/>. /// If the <paramref name="cacheProvider" /> provides a value, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider" /> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider" />, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="cacheKeyStrategy">The cache key strategy.</param> /// <param name="onCacheError">Delegate to call if an exception is thrown when attempting to get a value from or put a value into the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> /// <exception cref="ArgumentNullException">cacheKeyStrategy</exception> public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func <Context, string> cacheKeyStrategy, Action <Context, string, Exception> onCacheError = null) { if (cacheProvider == null) { throw new ArgumentNullException(nameof(cacheProvider)); } if (ttlStrategy == null) { throw new ArgumentNullException(nameof(ttlStrategy)); } if (cacheKeyStrategy == null) { throw new ArgumentNullException(nameof(cacheKeyStrategy)); } onCacheError = onCacheError ?? ((_, __, ___) => { }); Action <Context, string> emptyDelegate = (_, __) => { }; return(new CachePolicy(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError)); }
internal AsyncCachePolicy( IAsyncCacheProvider asyncCacheProvider, ITtlStrategy ttlStrategy, Func <Context, string> cacheKeyStrategy, Action <Context, string> onCacheGet, Action <Context, string> onCacheMiss, Action <Context, string> onCachePut, Action <Context, string, Exception> onCacheGetError, Action <Context, string, Exception> onCachePutError) { _asyncCacheProvider = asyncCacheProvider; _ttlStrategy = ttlStrategy; _cacheKeyStrategy = cacheKeyStrategy; _onCacheGet = onCacheGet; _onCachePut = onCachePut; _onCacheMiss = onCacheMiss; _onCacheGetError = onCacheGetError; _onCachePutError = onCachePutError; }
internal CachePolicy( ISyncCacheProvider syncCacheProvider, ITtlStrategy ttlStrategy, Func <Context, string> cacheKeyStrategy, Action <Context, string> onCacheGet, Action <Context, string> onCacheMiss, Action <Context, string> onCachePut, Action <Context, string, Exception> onCacheGetError, Action <Context, string, Exception> onCachePutError) : base((action, context, cancellationToken) => action(context, cancellationToken), // Pass-through/NOOP policy action, for void-returning calls through a cache policy. PredicateHelper.EmptyExceptionPredicates) { _syncCacheProvider = syncCacheProvider; _ttlStrategy = ttlStrategy; _cacheKeyStrategy = cacheKeyStrategy; _onCacheGet = onCacheGet; _onCachePut = onCachePut; _onCacheMiss = onCacheMiss; _onCacheGetError = onCacheGetError; _onCachePutError = onCachePutError; }
internal CachePolicy( IAsyncCacheProvider asyncCacheProvider, ITtlStrategy ttlStrategy, Func <Context, string> cacheKeyStrategy, Action <Context, string> onCacheGet, Action <Context, string> onCacheMiss, Action <Context, string> onCachePut, Action <Context, string, Exception> onCacheGetError, Action <Context, string, Exception> onCachePutError) : base((func, context, cancellationToken, continueOnCapturedContext) => func(context, cancellationToken), // Pass-through/NOOP policy action, for void-returning executions through the cache policy. PredicateHelper.EmptyExceptionPredicates) { _asyncCacheProvider = asyncCacheProvider; _ttlStrategy = ttlStrategy; _cacheKeyStrategy = cacheKeyStrategy; _onCacheGet = onCacheGet; _onCachePut = onCachePut; _onCacheMiss = onCacheMiss; _onCacheGetError = onCacheGetError; _onCachePutError = onCachePutError; }
/// <summary> /// <para>Builds a <see cref="Policy"/> that will function like a result cache for delegate executions returning a result.</para> /// <para>Before executing a delegate returning a result, checks whether the <paramref name="cacheProvider"/> holds a value for the cache key specified by <see cref="M:Context.ExecutionKey"/> /// If the <paramref name="cacheProvider"/> provides a value, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider"/> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider"/>, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="onCacheError">Delegate to call if an exception is thrown when attempting to get a value from or put a value into the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action <Context, string, Exception> onCacheError = null) { return(CacheAsync(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError)); }
/// <summary> /// <para>Builds a <see cref="Policy" /> that will function like a result cache for delegate executions returning a <typeparamref name="TResult"/>.</para> /// <para>Before executing a delegate, checks whether the <paramref name="cacheProvider" /> holds a value for the cache key determined by applying the <paramref name="cacheKeyStrategy"/> to the execution <see cref="Context"/>. /// If the <paramref name="cacheProvider" /> provides a value, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider" /> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider" />, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="cacheKeyStrategy">The cache key strategy.</param> /// <param name="onCacheError">Delegate to call if an exception is thrown when attempting to get a value from or put a value into the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheKeyStrategy</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> /// <exception cref="ArgumentNullException">cacheProvider</exception> public static CachePolicy <TResult> CacheAsync <TResult>(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func <Context, string> cacheKeyStrategy, Action <Context, string, Exception> onCacheError = null) { if (cacheProvider == null) { throw new ArgumentNullException(nameof(cacheProvider)); } return(CacheAsync <TResult>(cacheProvider.AsyncFor <TResult>(), ttlStrategy, cacheKeyStrategy, onCacheError)); }
internal GenericTtlStrategy(ITtlStrategy ttlStrategy) => _wrappedTtlStrategy = ttlStrategy ?? throw new ArgumentNullException(nameof(ttlStrategy));
/// <summary> /// Provides a strongly <typeparamref name="TResult"/>-typed version of the supplied <see cref="ITtlStrategy"/> /// </summary> /// <typeparam name="TResult">The type the returned <see cref="ITtlStrategy{TResult}"/> will handle.</typeparam> /// <param name="ttlStrategy">The non-generic ttl strategy to wrap.</param> /// <returns>ITtlStrategy{TCacheFormat}.</returns> internal static ITtlStrategy <TResult> For <TResult>(this ITtlStrategy ttlStrategy) => new GenericTtlStrategy <TResult>(ttlStrategy);
/// <summary> /// <para>Builds a <see cref="Policy" /> that will function like a result cache for delegate executions returning a result.</para> /// <para>Before executing a delegate returning a result, checks whether the <paramref name="cacheProvider"/> holds a value for the cache key specified by <see cref="M:Context.OperationKey"/>. /// If the <paramref name="cacheProvider"/> provides a value from cache, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider"/> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider"/>, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="onCacheError">Delegate to call if an exception is thrown when attempting to get a value from or put a value into the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action <Context, string, Exception> onCacheError = null) => Cache(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError);
internal static TResult Implementation <TResult>( ISyncCacheProvider <TResult> cacheProvider, ITtlStrategy ttlStrategy, Func <Context, string> cacheKeyStrategy, Func <Context, CancellationToken, TResult> action, Context context, CancellationToken cancellationToken, 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(action(context, cancellationToken)); } TResult valueFromCache; try { valueFromCache = cacheProvider.Get(cacheKey); } catch (Exception ex) { valueFromCache = default(TResult); onCacheGetError(context, cacheKey, ex); } if (valueFromCache != null && !valueFromCache.Equals(default(TResult))) { onCacheGet(context, cacheKey); return(valueFromCache); } else { onCacheMiss(context, cacheKey); } TResult result = action(context, cancellationToken); Ttl ttl = ttlStrategy.GetTtl(context); if (ttl.Timespan > TimeSpan.Zero) { try { cacheProvider.Put(cacheKey, result, ttl); onCachePut(context, cacheKey); } catch (Exception ex) { onCachePutError(context, cacheKey, ex); } } return(result); }
/// <summary> /// Provides a strongly <typeparamref name="TResult"/>-typed version of the supplied <see cref="ITtlStrategy"/> /// </summary> /// <typeparam name="TResult">The type the returned <see cref="ITtlStrategy{TResult}"/> will handle.</typeparam> /// <param name="ttlStrategy">The non-generic ttl strategy to wrap.</param> /// <returns>ITtlStrategy{TCacheFormat}.</returns> internal static ITtlStrategy <TResult> For <TResult>(this ITtlStrategy ttlStrategy) { return(new GenericTtlStrategy <TResult>(ttlStrategy)); }
/// <summary> /// <para>Builds a <see cref="Policy"/> that will function like a result cache for delegate executions returning a <typeparamref name="TResult"/>.</para> /// <para>Before executing a delegate, checks whether the <paramref name="cacheProvider"/> holds a value for the cache key specified by <see cref="M:Context.ExecutionKey"/>. /// If the <paramref name="cacheProvider"/> contains a value, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider"/> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider"/>, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="onCacheError">Delegate to call if an exception is thrown when attempting to get a value from or put a value into the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> public static CachePolicy <TResult> Cache <TResult>(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action <Context, string, Exception> onCacheError = null) { if (cacheProvider == null) { throw new ArgumentNullException(nameof(cacheProvider)); } return(Cache <TResult>(cacheProvider.For <TResult>(), ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError)); }
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)); } TResult valueFromCache; try { valueFromCache = await cacheProvider.GetAsync(cacheKey, cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext); } catch (Exception ex) { valueFromCache = default(TResult); onCacheGetError(context, cacheKey, ex); } if (valueFromCache != null && !valueFromCache.Equals(default(TResult))) { 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 && result != null && !result.Equals(default(TResult))) { try { await cacheProvider.PutAsync(cacheKey, result, ttl, cancellationToken, continueOnCapturedContext).ConfigureAwait(continueOnCapturedContext); onCachePut(context, cacheKey); } catch (Exception ex) { onCachePutError(context, cacheKey, ex); } } return(result); }
/// <summary> /// <para>Builds a <see cref="Policy"/> that will function like a result cache for delegate executions returning a <typeparamref name="TResult"/>.</para> /// <para>Before executing a delegate, checks whether the <paramref name="cacheProvider"/> holds a value for the cache key specified by <see cref="M:Context.ExecutionKey"/>. /// If the <paramref name="cacheProvider"/> contains a value, returns that value and does not execute the governed delegate. If the <paramref name="cacheProvider"/> does not provide a value, executes the governed delegate, stores the value with the <paramref name="cacheProvider"/>, then returns the value. /// </para> /// </summary> /// <param name="cacheProvider">The cache provider.</param> /// <param name="ttlStrategy">A strategy for specifying ttl for values to be cached.</param> /// <param name="onCacheError">Delegate to call if an exception is thrown when attempting to get a value from or put a value into the cache, passing the execution context, the cache key, and the exception.</param> /// <returns>The policy instance.</returns> /// <exception cref="ArgumentNullException">cacheProvider</exception> /// <exception cref="ArgumentNullException">ttlStrategy</exception> public static CachePolicy <TResult> Cache <TResult>(ISyncCacheProvider <TResult> cacheProvider, ITtlStrategy ttlStrategy, Action <Context, string, Exception> onCacheError = null) { return(Cache <TResult>(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError)); }
public static void CreateCachingPolicy <T>(this IServiceProvider provider, string cacheKey, ITtlStrategy strategy) { IPolicyRegistry <string> registry = provider.GetRequiredService <IPolicyRegistry <string> >(); IAsyncPolicy <T> policy = Policy.CacheAsync <T>(provider.GetRequiredService <IAsyncCacheProvider>().AsyncFor <T>(), strategy); registry.Add(cacheKey, policy); }