diff --git a/CHANGELOG.md b/CHANGELOG.md index e003080365c..ff737561c1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ + +## 5.7.0 +- Minor cache fixes +- Add ability to calculate cache Ttl based on item to cache +- Allow user-created custom policies + ## 5.6.1 - Extend PolicyWrap syntax with interfaces diff --git a/GitVersionConfig.yaml b/GitVersionConfig.yaml index 7bd2f8b5085..cd6af757234 100644 --- a/GitVersionConfig.yaml +++ b/GitVersionConfig.yaml @@ -1 +1 @@ -next-version: 5.6.1 \ No newline at end of file +next-version: 5.7.0 \ No newline at end of file diff --git a/README.md b/README.md index d0f384f69f5..fb6670114cd 100644 --- a/README.md +++ b/README.md @@ -951,6 +951,7 @@ For details of changes by release see the [change log](https://github.com/App-vN * [@reisenberger](https://github.com/reisenberger) - Add new .HandleInner(...) syntax for handling inner exceptions natively. * [@rjongeneelen](https://github.com/rjongeneelen) and [@reisenberger](https://github.com/reisenberger) - Allow PolicyWrap configuration to configure policies via interfaces. * [@reisenberger](https://github.com/reisenberger) - Performance improvements. +* [@awarrenlove](https://github.com/awarrenlove) - Add ability to calculate cache Ttl based on item to cache. # Sample Projects diff --git a/build.cake b/build.cake index 3c136d1a360..7c124a5df12 100644 --- a/build.cake +++ b/build.cake @@ -1,4 +1,4 @@ -/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// // ARGUMENTS /////////////////////////////////////////////////////////////////////////////// @@ -92,12 +92,16 @@ Teardown(_ => Task("__Clean") .Does(() => { - CleanDirectories(new DirectoryPath[] { + DirectoryPath[] cleanDirectories = new DirectoryPath[] { buildDir, - artifactsDir, testResultsDir, - nupkgDestDir - }); + nupkgDestDir, + artifactsDir + }; + + CleanDirectories(cleanDirectories); + + foreach(var path in cleanDirectories) { EnsureDirectoryExists(path); } foreach(var path in solutionPaths) { diff --git a/src/Polly.Net40Async.nuspec b/src/Polly.Net40Async.nuspec index a49b51cb613..dd44371ec08 100644 --- a/src/Polly.Net40Async.nuspec +++ b/src/Polly.Net40Async.nuspec @@ -15,6 +15,12 @@ v5.0 is a major release with significant new resilience policies: Timeout; Bulkhead Isolation; Fallback; Cache; and PolicyWrap. See release notes back to v5.0.0 for full details. + 5.7.0 + --------------------- + - Minor cache fixes + - Add ability to calculate cache Ttl based on item to cache + - Allow user-created custom policies + 5.6.1 --------------------- - Extend PolicyWrap syntax with interfaces diff --git a/src/Polly.NetStandard11/Properties/AssemblyInfo.cs b/src/Polly.NetStandard11/Properties/AssemblyInfo.cs index d36229ee178..55b87cb8fa6 100644 --- a/src/Polly.NetStandard11/Properties/AssemblyInfo.cs +++ b/src/Polly.NetStandard11/Properties/AssemblyInfo.cs @@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; [assembly: AssemblyTitle("Polly")] -[assembly: AssemblyVersion("5.6.1.0")] +[assembly: AssemblyVersion("5.7.0.0")] [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("Polly.NetStandard11.Specs")] \ No newline at end of file diff --git a/src/Polly.Shared/Caching/CacheEngine.cs b/src/Polly.Shared/Caching/CacheEngine.cs index 50a9c421b9a..59a128a83a2 100644 --- a/src/Polly.Shared/Caching/CacheEngine.cs +++ b/src/Polly.Shared/Caching/CacheEngine.cs @@ -7,7 +7,7 @@ internal static partial class CacheEngine { internal static TResult Implementation( ISyncCacheProvider cacheProvider, - ITtlStrategy ttlStrategy, + ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Func action, Context context, @@ -48,8 +48,8 @@ internal static TResult Implementation( TResult result = action(context, cancellationToken); - Ttl ttl = ttlStrategy.GetTtl(context); - if (ttl.Timespan > TimeSpan.Zero) + Ttl ttl = ttlStrategy.GetTtl(context, result); + if (ttl.Timespan > TimeSpan.Zero && result != null && !result.Equals(default(TResult))) { try { diff --git a/src/Polly.Shared/Caching/CacheEngineAsync.cs b/src/Polly.Shared/Caching/CacheEngineAsync.cs index e65abe6f7c5..aa77a2c20ce 100644 --- a/src/Polly.Shared/Caching/CacheEngineAsync.cs +++ b/src/Polly.Shared/Caching/CacheEngineAsync.cs @@ -8,7 +8,7 @@ internal static partial class CacheEngine { internal static async Task ImplementationAsync( IAsyncCacheProvider cacheProvider, - ITtlStrategy ttlStrategy, + ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Func> action, Context context, @@ -50,8 +50,8 @@ internal static async Task ImplementationAsync( TResult result = await action(context, cancellationToken).ConfigureAwait(continueOnCapturedContext); - Ttl ttl = ttlStrategy.GetTtl(context); - if (ttl.Timespan > TimeSpan.Zero) + Ttl ttl = ttlStrategy.GetTtl(context, result); + if (ttl.Timespan > TimeSpan.Zero && result != null && !result.Equals(default(TResult))) { try { diff --git a/src/Polly.Shared/Caching/CachePolicy.cs b/src/Polly.Shared/Caching/CachePolicy.cs index 23eb7b60d8d..ec66958be06 100644 --- a/src/Polly.Shared/Caching/CachePolicy.cs +++ b/src/Polly.Shared/Caching/CachePolicy.cs @@ -55,7 +55,7 @@ public override TResult ExecuteInternal(Func( _syncCacheProvider.For(), - _ttlStrategy, + _ttlStrategy.For(), _cacheKeyStrategy, action, context, @@ -75,7 +75,7 @@ public partial class CachePolicy : Policy, ICachePolicy syncCacheProvider, - ITtlStrategy ttlStrategy, + ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheGet, Action onCacheMiss, diff --git a/src/Polly.Shared/Caching/CachePolicyAsync.cs b/src/Polly.Shared/Caching/CachePolicyAsync.cs index 2a7bc036834..564bc022ccb 100644 --- a/src/Polly.Shared/Caching/CachePolicyAsync.cs +++ b/src/Polly.Shared/Caching/CachePolicyAsync.cs @@ -47,7 +47,7 @@ public override Task ExecuteAsyncInternal(Func( _asyncCacheProvider.AsyncFor(), - _ttlStrategy, + _ttlStrategy.For(), _cacheKeyStrategy, action, context, @@ -65,7 +65,7 @@ public partial class CachePolicy { internal CachePolicy( IAsyncCacheProvider asyncCacheProvider, - ITtlStrategy ttlStrategy, + ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheGet, Action onCacheMiss, diff --git a/src/Polly.Shared/Caching/CacheSyntax.cs b/src/Polly.Shared/Caching/CacheSyntax.cs index 7ebca3dd618..b7aa2fb0c9a 100644 --- a/src/Polly.Shared/Caching/CacheSyntax.cs +++ b/src/Polly.Shared/Caching/CacheSyntax.cs @@ -8,7 +8,7 @@ public partial class Policy /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key specified by . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -24,7 +24,7 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key specified by . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -41,7 +41,51 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy t /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) + { + return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action 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 emptyDelegate = (_, __) => { }; + + return Cache(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -59,7 +103,7 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -82,10 +126,116 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy t return Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); } + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// + /// + /// cacheProvider + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// + /// + /// cacheProvider + /// ttlStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// + /// + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -123,7 +273,44 @@ public static CachePolicy Cache( /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// + /// + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. diff --git a/src/Polly.Shared/Caching/CacheSyntaxAsync.cs b/src/Polly.Shared/Caching/CacheSyntaxAsync.cs index a793249c02a..4ab422fc39d 100644 --- a/src/Polly.Shared/Caching/CacheSyntaxAsync.cs +++ b/src/Polly.Shared/Caching/CacheSyntaxAsync.cs @@ -38,6 +38,50 @@ public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStra return CacheAsync(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); } + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action 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 emptyDelegate = (_, __) => { }; + + return new CachePolicy(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + } + /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . @@ -82,6 +126,106 @@ public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStra return new CachePolicy(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); } + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key. + /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key. + /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . @@ -106,8 +250,8 @@ public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStra /// onCacheGetError /// onCachePutError public static CachePolicy CacheAsync( - IAsyncCacheProvider cacheProvider, - ITtlStrategy ttlStrategy, + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action onCacheGet, Action onCacheMiss, @@ -118,6 +262,41 @@ public static CachePolicy CacheAsync( return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } + /// + /// Builds a that will function like a result cache for delegate executions returning a result. + /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + /// /// Builds a that will function like a result cache for delegate executions returning a result. /// Before executing a delegate returning a result, checks whether the holds a value for the cache key determined by applying the to the execution . diff --git a/src/Polly.Shared/Caching/CacheTResultSyntax.cs b/src/Polly.Shared/Caching/CacheTResultSyntax.cs index c9a44fc768c..3467c9c8c8d 100644 --- a/src/Polly.Shared/Caching/CacheTResultSyntax.cs +++ b/src/Polly.Shared/Caching/CacheTResultSyntax.cs @@ -8,7 +8,7 @@ public partial class Policy /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key specified by . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -26,7 +26,7 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvid /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key specified by . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -43,42 +43,50 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvid } /// - /// Builds a that will function like a result cache for delegate executions returning a . - /// Before executing a delegate, checks whether the holds a value for the cache key specified by . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. /// Duration (ttl) for which to cache values. + /// The cache key strategy. /// 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. /// The policy instance. /// cacheProvider - public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, Action onCacheError = null) + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) { - return Cache(cacheProvider, new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return Cache(cacheProvider.For(), new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); } /// - /// Builds a that will function like a result cache for delegate executions returning a . - /// Before executing a delegate, checks whether the holds a value for the cache key specified by . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. /// 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. /// The policy instance. /// cacheProvider /// ttlStrategy - public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action onCacheError = null) + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) { - return Cache(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return Cache(cacheProvider.For(), ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheError); } /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -98,7 +106,7 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvid /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -116,59 +124,158 @@ public static CachePolicy Cache(ISyncCacheProvider cacheProvid return Cache(cacheProvider.For(), ttlStrategy, cacheKeyStrategy, onCacheError); } + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return Cache(cacheProvider.For(), new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return Cache(cacheProvider.For(), ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. /// Duration (ttl) for which to cache values. /// The cache key strategy. - /// 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. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. /// The policy instance. /// cacheProvider /// cacheKeyStrategy - public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, Func cacheKeyStrategy, Action onCacheError = null) + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) { - return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy, onCacheError); + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return Cache(cacheProvider.For(), new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. /// A strategy for specifying ttl for values to be cached. /// The cache key strategy. - /// 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. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. /// The policy instance. /// cacheProvider /// ttlStrategy /// cacheKeyStrategy - public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheError = null) + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action 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)); - - onCacheError = onCacheError ?? ((_, __, ___) => { }); - - Action emptyDelegate = (_, __) => { }; - return new CachePolicy(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + return Cache(cacheProvider.For(), ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. - /// A strategy for specifying ttl for values to be cached. + /// Duration (ttl) for which to cache values. /// The cache key strategy. /// Delegate to call on a cache hit, when value is returned from cache. /// Delegate to call on a cache miss. @@ -177,7 +284,6 @@ public static CachePolicy Cache(ISyncCacheProvider ca /// 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. /// The policy instance. /// cacheProvider - /// ttlStrategy /// cacheKeyStrategy /// onCacheGet /// onCacheMiss @@ -185,22 +291,24 @@ public static CachePolicy Cache(ISyncCacheProvider ca /// onCacheGetError /// onCachePutError public static CachePolicy Cache( - ISyncCacheProvider cacheProvider, - ITtlStrategy ttlStrategy, - ICacheKeyStrategy cacheKeyStrategy, + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + Func cacheKeyStrategy, Action onCacheGet, Action onCacheMiss, Action onCachePut, Action onCacheGetError, Action onCachePutError) { - return Cache(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return Cache(cacheProvider.For(), new RelativeTtl(ttl), cacheKeyStrategy, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the contains a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -221,8 +329,508 @@ public static CachePolicy Cache( /// onCacheGetError /// onCachePutError public static CachePolicy Cache( - ISyncCacheProvider cacheProvider, - ITtlStrategy ttlStrategy, + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return Cache(cacheProvider.For(), ttlStrategy, cacheKeyStrategy, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key specified by . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// 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. + /// The policy instance. + /// cacheProvider + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, Action onCacheError = null) + { + return Cache(cacheProvider, new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key specified by . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action onCacheError = null) + { + return Cache(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key specified by . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action onCacheError = null) + { + return Cache(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) + { + return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) + { + onCacheError = onCacheError ?? ((_, __, ___) => { }); + + Action emptyDelegate = (_, __) => { }; + + return Cache(cacheProvider, ttlStrategy.For(), cacheKeyStrategy.GetCacheKey, + emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) + { + onCacheError = onCacheError ?? ((_, __, ___) => { }); + + Action emptyDelegate = (_, __) => { }; + + return Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, + onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl, Func cacheKeyStrategy, Action onCacheError = null) + { + return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheError = null) + { + onCacheError = onCacheError ?? ((_, __, ___) => { }); + + Action emptyDelegate = (_, __) => { }; + + return Cache(cacheProvider, ttlStrategy.For(), cacheKeyStrategy, + emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy Cache(ISyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheError = null) + { + onCacheError = onCacheError ?? ((_, __, ___) => { }); + + Action emptyDelegate = (_, __) => { }; + + return Cache(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, + onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, + onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, + onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + TimeSpan ttl, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy, onCacheGet, onCacheMiss, + onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return Cache(cacheProvider, ttlStrategy.For(), cacheKeyStrategy, onCacheGet, onCacheMiss, + onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy Cache( + ISyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheGet, Action onCacheMiss, diff --git a/src/Polly.Shared/Caching/CacheTResultSyntaxAsync.cs b/src/Polly.Shared/Caching/CacheTResultSyntaxAsync.cs index 9f2d6db8f25..762c4ace1d2 100644 --- a/src/Polly.Shared/Caching/CacheTResultSyntaxAsync.cs +++ b/src/Polly.Shared/Caching/CacheTResultSyntaxAsync.cs @@ -8,7 +8,7 @@ public partial class Policy /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key specified by . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -26,7 +26,7 @@ public static CachePolicy CacheAsync(IAsyncCacheProvider cache /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key specified by . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -43,42 +43,50 @@ public static CachePolicy CacheAsync(IAsyncCacheProvider cache } /// - /// Builds a that will function like a result cache for delegate executions returning a . - /// Before executing a delegate, checks whether the holds a value for the cache key specified by . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. /// Duration (ttl) for which to cache values. + /// The cache key strategy. /// 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. /// The policy instance. /// cacheProvider - public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, Action onCacheError = null) + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) { - return CacheAsync(cacheProvider, new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return CacheAsync(cacheProvider.AsyncFor(), new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); } /// - /// Builds a that will function like a result cache for delegate executions returning a . - /// Before executing a delegate, checks whether the holds a value for the cache key specified by . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. /// A strategy for specifying ttl for values to be cached. - /// The policy instance. + /// The cache key strategy. /// 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. + /// The policy instance. /// cacheProvider /// ttlStrategy - public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action onCacheError = null) + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) { - return CacheAsync(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return CacheAsync(cacheProvider.AsyncFor(), ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheError); } /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -86,8 +94,8 @@ public static CachePolicy CacheAsync(IAsyncCacheProviderThe cache key strategy. /// 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. /// The policy instance. - /// cacheKeyStrategy /// cacheProvider + /// cacheKeyStrategy public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, Func cacheKeyStrategy, Action onCacheError = null) { if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); @@ -98,7 +106,7 @@ public static CachePolicy CacheAsync(IAsyncCacheProvider cache /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -106,9 +114,9 @@ public static CachePolicy CacheAsync(IAsyncCacheProvider cache /// The cache key strategy. /// 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. /// The policy instance. - /// cacheKeyStrategy - /// ttlStrategy /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheError = null) { if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); @@ -118,53 +126,114 @@ public static CachePolicy CacheAsync(IAsyncCacheProvider cache /// /// Builds a that will function like a result cache for delegate executions returning a . - /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. /// Duration (ttl) for which to cache values. - /// The cache key strategy. - /// 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. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. /// The policy instance. - /// cacheKeyStrategy /// cacheProvider - public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, Func cacheKeyStrategy, Action onCacheError = null) + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) { - return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy, onCacheError); + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return CacheAsync(cacheProvider.AsyncFor(), new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } /// /// Builds a that will function like a result cache for delegate executions returning a . - /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. /// A strategy for specifying ttl for values to be cached. - /// The cache key strategy. - /// 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. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. /// The policy instance. - /// cacheKeyStrategy - /// ttlStrategy /// cacheProvider - public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheError = null) + /// ttlStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action 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)); - onCacheError = onCacheError ?? ((_, __, ___) => { }); + return CacheAsync(cacheProvider.AsyncFor(), ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } - Action emptyDelegate = (_, __) => { }; + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); - return new CachePolicy(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + return CacheAsync(cacheProvider.AsyncFor(), new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -185,8 +254,8 @@ public static CachePolicy CacheAsync(IAsyncCacheProvideronCacheGetError /// onCachePutError public static CachePolicy CacheAsync( - IAsyncCacheProvider cacheProvider, - ITtlStrategy ttlStrategy, + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action onCacheGet, Action onCacheMiss, @@ -194,13 +263,52 @@ public static CachePolicy CacheAsync( Action onCacheGetError, Action onCachePutError) { - return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return CacheAsync(cacheProvider.AsyncFor(), ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return CacheAsync(cacheProvider.AsyncFor(), new RelativeTtl(ttl), cacheKeyStrategy, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); } /// /// Builds a that will function like a result cache for delegate executions returning a . /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . - /// If the provides a value, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. /// /// /// The cache provider. @@ -221,7 +329,7 @@ public static CachePolicy CacheAsync( /// onCacheGetError /// onCachePutError public static CachePolicy CacheAsync( - IAsyncCacheProvider cacheProvider, + IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheGet, @@ -231,6 +339,501 @@ public static CachePolicy CacheAsync( Action onCachePutError) { if (cacheProvider == null) throw new ArgumentNullException(nameof(cacheProvider)); + + return CacheAsync(cacheProvider.AsyncFor(), ttlStrategy, cacheKeyStrategy, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key specified by . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// 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. + /// The policy instance. + /// cacheProvider + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, Action onCacheError = null) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key specified by . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action onCacheError = null) + { + return CacheAsync(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key specified by . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Action onCacheError = null) + { + return CacheAsync(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) + { + onCacheError = onCacheError ?? ((_, __, ___) => { }); + + Action emptyDelegate = (_, __) => { }; + + return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, ICacheKeyStrategy cacheKeyStrategy, Action onCacheError = null) + { + onCacheError = onCacheError ?? ((_, __, ___) => { }); + + Action emptyDelegate = (_, __) => { }; + + return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl, Func cacheKeyStrategy, Action onCacheError = null) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheError = null) + { + onCacheError = onCacheError ?? ((_, __, ___) => { }); + + Action emptyDelegate = (_, __) => { }; + + return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + public static CachePolicy CacheAsync(IAsyncCacheProvider cacheProvider, ITtlStrategy ttlStrategy, Func cacheKeyStrategy, Action onCacheError = null) + { + onCacheError = onCacheError ?? ((_, __, ___) => { }); + + Action emptyDelegate = (_, __) => { }; + + return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy, emptyDelegate, emptyDelegate, emptyDelegate, onCacheError, onCacheError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, + onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, ttlStrategy.For(), DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key. + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, ttlStrategy, DefaultCacheKeyStrategy.Instance.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, + onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, ttlStrategy.For(), cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + ICacheKeyStrategy cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, ttlStrategy, cacheKeyStrategy.GetCacheKey, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// Duration (ttl) for which to cache values. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + TimeSpan ttl, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, new RelativeTtl(ttl), cacheKeyStrategy, onCacheGet, onCacheMiss, + onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action onCachePutError) + { + return CacheAsync(cacheProvider, ttlStrategy.For(), cacheKeyStrategy, onCacheGet, onCacheMiss, onCachePut, onCacheGetError, onCachePutError); + } + + /// + /// Builds a that will function like a result cache for delegate executions returning a . + /// Before executing a delegate, checks whether the holds a value for the cache key determined by applying the to the execution . + /// If the provides a value from cache, returns that value and does not execute the governed delegate. If the does not provide a value, executes the governed delegate, stores the value with the , then returns the value. + /// + /// + /// The cache provider. + /// A strategy for specifying ttl for values to be cached. + /// The cache key strategy. + /// Delegate to call on a cache hit, when value is returned from cache. + /// Delegate to call on a cache miss. + /// Delegate to call on cache put. + /// 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. + /// 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. + /// The policy instance. + /// cacheProvider + /// ttlStrategy + /// cacheKeyStrategy + /// onCacheGet + /// onCacheMiss + /// onCachePut + /// onCacheGetError + /// onCachePutError + public static CachePolicy CacheAsync( + IAsyncCacheProvider cacheProvider, + ITtlStrategy ttlStrategy, + Func cacheKeyStrategy, + Action onCacheGet, + Action onCacheMiss, + Action onCachePut, + Action onCacheGetError, + Action 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)); diff --git a/src/Polly.Shared/Caching/ContextualTtl.cs b/src/Polly.Shared/Caching/ContextualTtl.cs index decc829ba29..4c1bbb479a5 100644 --- a/src/Polly.Shared/Caching/ContextualTtl.cs +++ b/src/Polly.Shared/Caching/ContextualTtl.cs @@ -24,8 +24,9 @@ public class ContextualTtl : ITtlStrategy /// Gets the TimeSpan for which to keep an item about to be cached, which may be influenced by data in the execution context. /// /// The execution context. + /// The execution result. /// TimeSpan. - public Ttl GetTtl(Context context) + public Ttl GetTtl(Context context, object result) { if (!context.ContainsKey(TimeSpanKey)) return _noTtl; bool sliding = context.ContainsKey(SlidingExpirationKey) ? context[SlidingExpirationKey] as bool? ?? false : false; diff --git a/src/Polly.Shared/Caching/GenericTtlStrategy.cs b/src/Polly.Shared/Caching/GenericTtlStrategy.cs new file mode 100644 index 00000000000..906b2f00327 --- /dev/null +++ b/src/Polly.Shared/Caching/GenericTtlStrategy.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Polly.Utilities; + +namespace Polly.Caching +{ + /// + /// Represents a strongly-typed wrapper of a non-generic strategy. + /// + internal class GenericTtlStrategy : ITtlStrategy + { + private readonly ITtlStrategy _wrappedTtlStrategy; + + internal GenericTtlStrategy(ITtlStrategy ttlStrategy) + { + _wrappedTtlStrategy = ttlStrategy ?? throw new ArgumentNullException(nameof(ttlStrategy)); + } + + /// + /// Gets a TTL for a cacheable item, given the current execution context and result. + /// + /// The execution context. + /// The execution result. + /// A representing the remaining Ttl of the cached item. + public Ttl GetTtl(Context context, TResult result) + { + return _wrappedTtlStrategy.GetTtl(context, (object)result); + } + } +} diff --git a/src/Polly.Shared/Caching/ITtlStrategy.cs b/src/Polly.Shared/Caching/ITtlStrategy.cs index 208c5971cef..c73f7fb946f 100644 --- a/src/Polly.Shared/Caching/ITtlStrategy.cs +++ b/src/Polly.Shared/Caching/ITtlStrategy.cs @@ -5,13 +5,22 @@ namespace Polly.Caching /// /// Defines a strategy for providing time-to-live durations for cacheable results. /// - public interface ITtlStrategy + public interface ITtlStrategy : ITtlStrategy + { + + } + + /// + /// Defines a strategy for providing time-to-live durations for cacheable results. + /// + public interface ITtlStrategy { /// /// Gets a TTL for a cacheable item, given the current execution context. /// /// The execution context. + /// The execution result. /// A representing the remaining Ttl of the cached item. - Ttl GetTtl(Context context); + Ttl GetTtl(Context context, TResult result); } } diff --git a/src/Polly.Shared/Caching/NonSlidingTtl.cs b/src/Polly.Shared/Caching/NonSlidingTtl.cs index b3ba3857a65..730faddb322 100644 --- a/src/Polly.Shared/Caching/NonSlidingTtl.cs +++ b/src/Polly.Shared/Caching/NonSlidingTtl.cs @@ -28,8 +28,9 @@ protected NonSlidingTtl(DateTimeOffset absoluteExpirationTime) /// Gets a TTL for a cacheable item, given the current execution context. /// /// The execution context. + /// The execution result. /// A representing the remaining Ttl of the cached item. - public Ttl GetTtl(Context context) + public Ttl GetTtl(Context context, object result) { TimeSpan untilPointInTime = absoluteExpirationTime.Subtract(SystemClock.DateTimeOffsetUtcNow()); TimeSpan remaining = untilPointInTime > TimeSpan.Zero ? untilPointInTime : TimeSpan.Zero; diff --git a/src/Polly.Shared/Caching/ResultTtl.cs b/src/Polly.Shared/Caching/ResultTtl.cs new file mode 100644 index 00000000000..1c4c153a044 --- /dev/null +++ b/src/Polly.Shared/Caching/ResultTtl.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Polly.Caching +{ + /// + /// Defines a ttl strategy which can calculate a duration to cache items dynamically based on the execution context and result of the execution. + /// + /// The type of results that the ttl calculation function will take as an input parameter. + public class ResultTtl : ITtlStrategy + { + private readonly Func _ttlFunc; + + /// + /// Constructs a new instance of the ttl strategy, with a func calculating based on the value to cache. + /// + /// The function to calculate the TTL for which cache items should be considered valid. + public ResultTtl(Func ttlFunc) + { + if (ttlFunc == null) throw new ArgumentNullException(nameof(ttlFunc)); + _ttlFunc = (context, result) => ttlFunc(result); + } + + /// + /// Constructs a new instance of the ttl strategy, with a func calculating based on the execution and value to cache. + /// + /// The function to calculate the TTL for which cache items should be considered valid. + public ResultTtl(Func ttlFunc) + { + _ttlFunc = ttlFunc ?? throw new ArgumentNullException(nameof(ttlFunc)); + } + + /// + /// Gets a TTL for the cacheable item. + /// + /// The execution context. + /// The execution result. + /// A representing the remaining Ttl of the cached item. + + public Ttl GetTtl(Context context, TResult result) + { + return _ttlFunc(context, result); + } + } +} diff --git a/src/Polly.Shared/Caching/SlidingTtl.cs b/src/Polly.Shared/Caching/SlidingTtl.cs index 6c78c0dc6e7..2877d8a7670 100644 --- a/src/Polly.Shared/Caching/SlidingTtl.cs +++ b/src/Polly.Shared/Caching/SlidingTtl.cs @@ -27,9 +27,10 @@ public SlidingTtl(TimeSpan slidingTtl) /// Gets a TTL for the cacheable item. /// /// The execution context. + /// The execution result. /// A representing the remaining Ttl of the cached item. - public Ttl GetTtl(Context context) + public Ttl GetTtl(Context context, object result) { return ttl; } diff --git a/src/Polly.Shared/Caching/TtlStrategyExtensions.cs b/src/Polly.Shared/Caching/TtlStrategyExtensions.cs new file mode 100644 index 00000000000..56d51dda190 --- /dev/null +++ b/src/Polly.Shared/Caching/TtlStrategyExtensions.cs @@ -0,0 +1,19 @@ +namespace Polly.Caching +{ + /// + /// Class that provides helper methods for configuring TtlStrategies. + /// + internal static class TtlStrategyExtensions + { + /// + /// Provides a strongly -typed version of the supplied + /// + /// The type the returned will handle. + /// The non-generic ttl strategy to wrap. + /// ITtlStrategy{TCacheFormat}. + internal static ITtlStrategy For(this ITtlStrategy ttlStrategy) + { + return new GenericTtlStrategy(ttlStrategy); + } + } +} diff --git a/src/Polly.Shared/ExceptionPredicate.cs b/src/Polly.Shared/ExceptionPredicate.cs index 138abac68be..03cc9dfd4d8 100644 --- a/src/Polly.Shared/ExceptionPredicate.cs +++ b/src/Polly.Shared/ExceptionPredicate.cs @@ -2,5 +2,10 @@ namespace Polly { - internal delegate Exception ExceptionPredicate(Exception ex); + /// + /// A predicate that can be run against a passed . + /// + /// The passed exception, against which to evaluate the predicate. + /// A matched ; or null, if an exception was not matched. ExceptionPredicate implementations may return the passed Exception , indicating that it matched the predicate. They may also return inner exceptions of the passed Exception , to indicate that the returned inner exception matched the predicate. + public delegate Exception ExceptionPredicate(Exception ex); } \ No newline at end of file diff --git a/src/Polly.Shared/Policy.TResult.cs b/src/Polly.Shared/Policy.TResult.cs index d9873a4de9b..7fb7f8560df 100644 --- a/src/Polly.Shared/Policy.TResult.cs +++ b/src/Polly.Shared/Policy.TResult.cs @@ -16,7 +16,13 @@ public abstract partial class Policy : ISyncPolicy internal IEnumerable ExceptionPredicates { get; } internal IEnumerable> ResultPredicates { get; } - internal Policy( + /// + /// Constructs a new instance of a derived type with the passed , and + /// + /// The execution policy that will be applied to delegates executed synchronously through the policy. + /// Predicates indicating which exceptions the policy should handle. + /// Predicates indicating which results the policy should handle. + protected Policy( Func, Context, CancellationToken, TResult> executionPolicy, IEnumerable exceptionPredicates, IEnumerable> resultPredicates diff --git a/src/Polly.Shared/Policy.cs b/src/Polly.Shared/Policy.cs index a0ff568ad71..fe4a84b20c9 100644 --- a/src/Polly.Shared/Policy.cs +++ b/src/Polly.Shared/Policy.cs @@ -16,7 +16,12 @@ public abstract partial class Policy : ISyncPolicy private readonly Action, Context, CancellationToken> _exceptionPolicy; internal IEnumerable ExceptionPredicates { get; } - internal Policy( + /// + /// Constructs a new instance of a derived type with the passed and + /// + /// The execution policy that will be applied to delegates executed synchronously through the policy. + /// Predicates indicating which exceptions the policy should handle. + protected Policy( Action, Context, CancellationToken> exceptionPolicy, IEnumerable exceptionPredicates) { diff --git a/src/Polly.Shared/PolicyAsync.TResult.cs b/src/Polly.Shared/PolicyAsync.TResult.cs index 7320b36c277..6f92e520d9e 100644 --- a/src/Polly.Shared/PolicyAsync.TResult.cs +++ b/src/Polly.Shared/PolicyAsync.TResult.cs @@ -12,7 +12,13 @@ public abstract partial class Policy : IAsyncPolicy { private readonly Func>, Context, CancellationToken, bool, Task> _asyncExecutionPolicy; - internal Policy( + /// + /// Constructs a new instance of a derived type with the passed , and + /// + /// The execution policy that will be applied to delegates executed asychronously through the asynchronous policy. + /// Predicates indicating which exceptions the policy should handle. + /// Predicates indicating which results the policy should handle. + protected Policy( Func>, Context, CancellationToken, bool, Task> asyncExecutionPolicy, IEnumerable exceptionPredicates, IEnumerable> resultPredicates) diff --git a/src/Polly.Shared/PolicyAsync.cs b/src/Polly.Shared/PolicyAsync.cs index 6e3a6153b18..b29721cbd01 100644 --- a/src/Polly.Shared/PolicyAsync.cs +++ b/src/Polly.Shared/PolicyAsync.cs @@ -11,7 +11,12 @@ public abstract partial class Policy : IAsyncPolicy { private readonly Func, Context, CancellationToken, bool, Task> _asyncExceptionPolicy; - internal Policy( + /// + /// Constructs a new instance of a derived type with the passed and . + /// + /// The execution policy that will be applied to delegates executed asychronously through the asynchronous policy. + /// Predicates indicating which exceptions the policy should handle. + protected Policy( Func, Context, CancellationToken, bool, Task> asyncExceptionPolicy, IEnumerable exceptionPredicates) { diff --git a/src/Polly.Shared/Polly.Shared.projitems b/src/Polly.Shared/Polly.Shared.projitems index 294203281cb..4447fba44ad 100644 --- a/src/Polly.Shared/Polly.Shared.projitems +++ b/src/Polly.Shared/Polly.Shared.projitems @@ -31,6 +31,7 @@ + @@ -39,10 +40,12 @@ + + diff --git a/src/Polly.Shared/ResultPredicate.cs b/src/Polly.Shared/ResultPredicate.cs index e41ff29bc5a..0821def18ae 100644 --- a/src/Polly.Shared/ResultPredicate.cs +++ b/src/Polly.Shared/ResultPredicate.cs @@ -1,4 +1,11 @@ namespace Polly { - internal delegate bool ResultPredicate(TResult result); + /// + /// A predicate that can be run against a passed result value of type . + /// + /// The passed result, against which to evaluate the predicate. + /// The type of results which this predicate can evaluate. + /// True if the passed matched the predicate; otherwise, false. + + public delegate bool ResultPredicate(TResult result); } \ No newline at end of file diff --git a/src/Polly.SharedSpecs/Caching/AbsoluteTtlSpecs.cs b/src/Polly.SharedSpecs/Caching/AbsoluteTtlSpecs.cs index e6534ea08c6..8252e2c69e8 100644 --- a/src/Polly.SharedSpecs/Caching/AbsoluteTtlSpecs.cs +++ b/src/Polly.SharedSpecs/Caching/AbsoluteTtlSpecs.cs @@ -38,7 +38,7 @@ public void Should_return_zero_ttl_if_configured_to_expire_in_past() { AbsoluteTtl ttlStrategy = new AbsoluteTtl(SystemClock.DateTimeOffsetUtcNow().Subtract(TimeSpan.FromTicks(1))); - ttlStrategy.GetTtl(new Context("someExecutionKey")).Timespan.Should().Be(TimeSpan.Zero); + ttlStrategy.GetTtl(new Context("someExecutionKey"), null).Timespan.Should().Be(TimeSpan.Zero); } [Fact] @@ -50,7 +50,7 @@ public void Should_return_timespan_reflecting_time_until_expiry() AbsoluteTtl ttlStrategy = new AbsoluteTtl(tomorrow); SystemClock.DateTimeOffsetUtcNow = () => today; - ttlStrategy.GetTtl(new Context("someExecutionKey")).Timespan.Should().Be(TimeSpan.FromDays(1)); + ttlStrategy.GetTtl(new Context("someExecutionKey"), null).Timespan.Should().Be(TimeSpan.FromDays(1)); } public void Dispose() diff --git a/src/Polly.SharedSpecs/Caching/CacheAsyncSpecs.cs b/src/Polly.SharedSpecs/Caching/CacheAsyncSpecs.cs index 6ca601cc7e0..6dea7072c7a 100644 --- a/src/Polly.SharedSpecs/Caching/CacheAsyncSpecs.cs +++ b/src/Polly.SharedSpecs/Caching/CacheAsyncSpecs.cs @@ -538,6 +538,34 @@ public async Task Should_execute_oncachemiss_and_oncacheput_if_cache_does_not_ho keyPassedToOnCachePut.Should().Be(executionKey); } + [Fact] + public async Task Should_execute_oncachemiss_but_not_oncacheput_if_cache_does_not_hold_value_and_returned_value_not_worth_caching() + { + const string valueToReturn = null; + + const string executionKey = "SomeExecutionKey"; + string keyPassedToOnCacheMiss = null; + string keyPassedToOnCachePut = null; + + Context contextToExecute = new Context(executionKey); + Context contextPassedToOnCacheMiss = null; + Context contextPassedToOnCachePut = null; + + Action noErrorHandling = (_, __, ___) => { }; + Action emptyDelegate = (_, __) => { }; + Action onCacheMiss = (ctx, key) => { contextPassedToOnCacheMiss = ctx; keyPassedToOnCacheMiss = key; }; + Action onCachePut = (ctx, key) => { contextPassedToOnCachePut = ctx; keyPassedToOnCachePut = key; }; + + IAsyncCacheProvider stubCacheProvider = new StubCacheProvider(); + CachePolicy cache = Policy.CacheAsync(stubCacheProvider, new RelativeTtl(TimeSpan.MaxValue), DefaultCacheKeyStrategy.Instance, emptyDelegate, onCacheMiss, onCachePut, noErrorHandling, noErrorHandling); + + ((string)await stubCacheProvider.GetAsync(executionKey, CancellationToken.None, false).ConfigureAwait(false)).Should().BeNull(); + (await cache.ExecuteAsync(async () => { await TaskHelper.EmptyTask.ConfigureAwait(false); return valueToReturn; }, contextToExecute).ConfigureAwait(false)).Should().Be(valueToReturn); + + contextPassedToOnCachePut.Should().BeNull(); + keyPassedToOnCachePut.Should().BeNull(); + } + [Fact] public async Task Should_not_execute_oncachemiss_if_dont_query_cache_because_cache_key_not_set() { diff --git a/src/Polly.SharedSpecs/Caching/CacheSpecs.cs b/src/Polly.SharedSpecs/Caching/CacheSpecs.cs index 02e457454b7..1df548e58f2 100644 --- a/src/Polly.SharedSpecs/Caching/CacheSpecs.cs +++ b/src/Polly.SharedSpecs/Caching/CacheSpecs.cs @@ -522,6 +522,37 @@ public void Should_execute_oncachemiss_and_oncacheput_if_cache_does_not_hold_val keyPassedToOnCachePut.Should().Be(executionKey); } + [Fact] + public void Should_execute_oncachemiss_but_not_oncacheput_if_cache_does_not_hold_value_and_returned_value_not_worth_caching() + { + const string valueToReturn = null; + + const string executionKey = "SomeExecutionKey"; + string keyPassedToOnCacheMiss = null; + string keyPassedToOnCachePut = null; + + Context contextToExecute = new Context(executionKey); + Context contextPassedToOnCacheMiss = null; + Context contextPassedToOnCachePut = null; + + Action noErrorHandling = (_, __, ___) => { }; + Action emptyDelegate = (_, __) => { }; + Action onCacheMiss = (ctx, key) => { contextPassedToOnCacheMiss = ctx; keyPassedToOnCacheMiss = key; }; + Action onCachePut = (ctx, key) => { contextPassedToOnCachePut = ctx; keyPassedToOnCachePut = key; }; + + ISyncCacheProvider stubCacheProvider = new StubCacheProvider(); + CachePolicy cache = Policy.Cache(stubCacheProvider, new RelativeTtl(TimeSpan.MaxValue), DefaultCacheKeyStrategy.Instance, emptyDelegate, onCacheMiss, onCachePut, noErrorHandling, noErrorHandling); + + stubCacheProvider.Get(executionKey).Should().BeNull(); + cache.Execute(() => { return valueToReturn; }, contextToExecute).Should().Be(valueToReturn); + + contextPassedToOnCacheMiss.Should().BeSameAs(contextToExecute); + keyPassedToOnCacheMiss.Should().Be(executionKey); + + contextPassedToOnCachePut.Should().BeNull(); + keyPassedToOnCachePut.Should().BeNull(); + } + [Fact] public void Should_not_execute_oncachemiss_if_dont_query_cache_because_cache_key_not_set() { diff --git a/src/Polly.SharedSpecs/Caching/ContextualTtlSpecs.cs b/src/Polly.SharedSpecs/Caching/ContextualTtlSpecs.cs index 803d9902379..ae8cb0735d2 100644 --- a/src/Polly.SharedSpecs/Caching/ContextualTtlSpecs.cs +++ b/src/Polly.SharedSpecs/Caching/ContextualTtlSpecs.cs @@ -12,7 +12,7 @@ public class ContextualTtlSpecs [Fact] public void Should_return_zero_if_no_value_set_on_context() { - new ContextualTtl().GetTtl(new Context("someExecutionKey")).Timespan.Should().Be(TimeSpan.Zero); + new ContextualTtl().GetTtl(new Context("someExecutionKey"), null).Timespan.Should().Be(TimeSpan.Zero); } [Fact] @@ -22,7 +22,7 @@ public void Should_return_zero_if_invalid_value_set_on_context() contextData[ContextualTtl.TimeSpanKey] = new object(); Context context = new Context(String.Empty, contextData); - new ContextualTtl().GetTtl(context).Timespan.Should().Be(TimeSpan.Zero); + new ContextualTtl().GetTtl(context, null).Timespan.Should().Be(TimeSpan.Zero); } [Fact] @@ -33,7 +33,7 @@ public void Should_return_value_set_on_context() contextData[ContextualTtl.TimeSpanKey] = ttl; Context context = new Context(String.Empty, contextData); - Ttl gotTtl = new ContextualTtl().GetTtl(context); + Ttl gotTtl = new ContextualTtl().GetTtl(context, null); gotTtl.Timespan.Should().Be(ttl); gotTtl.SlidingExpiration.Should().BeFalse(); } @@ -46,7 +46,7 @@ public void Should_return_negative_value_set_on_context() contextData[ContextualTtl.TimeSpanKey] = ttl; Context context = new Context(String.Empty, contextData); - Ttl gotTtl = new ContextualTtl().GetTtl(context); + Ttl gotTtl = new ContextualTtl().GetTtl(context, null); gotTtl.Timespan.Should().Be(ttl); gotTtl.SlidingExpiration.Should().BeFalse(); } diff --git a/src/Polly.SharedSpecs/Caching/RelativeTtlSpecs.cs b/src/Polly.SharedSpecs/Caching/RelativeTtlSpecs.cs index eaecd1af995..19f00d391b5 100644 --- a/src/Polly.SharedSpecs/Caching/RelativeTtlSpecs.cs +++ b/src/Polly.SharedSpecs/Caching/RelativeTtlSpecs.cs @@ -40,7 +40,7 @@ public void Should_return_configured_timespan() RelativeTtl ttlStrategy = new RelativeTtl(ttl); - Ttl retrieved = ttlStrategy.GetTtl(new Context("someExecutionKey")); + Ttl retrieved = ttlStrategy.GetTtl(new Context("someExecutionKey"), null); retrieved.Timespan.Should().BeCloseTo(ttl); retrieved.SlidingExpiration.Should().BeFalse(); } diff --git a/src/Polly.SharedSpecs/Caching/ResultTtlSpecs.cs b/src/Polly.SharedSpecs/Caching/ResultTtlSpecs.cs new file mode 100644 index 00000000000..1e9b78ceb52 --- /dev/null +++ b/src/Polly.SharedSpecs/Caching/ResultTtlSpecs.cs @@ -0,0 +1,70 @@ +using System; +using FluentAssertions; +using Polly.Caching; +using Polly.Specs.Helpers.Caching; +using Xunit; + +namespace Polly.Specs.Caching +{ + public class ResultTtlSpecs + { + [Fact] + public void Should_throw_when_func_is_null() + { + Action configure = () => new ResultTtl((Func)null); + + configure.ShouldThrow().And.ParamName.Should().Be("ttlFunc"); + } + + [Fact] + public void Should_throw_when_func_is_null_using_context() + { + Action configure = () => new ResultTtl((Func)null); + + configure.ShouldThrow().And.ParamName.Should().Be("ttlFunc"); + } + + [Fact] + public void Should_not_throw_when_func_is_set() + { + Action configure = () => new ResultTtl((result) => new Ttl()); + + configure.ShouldNotThrow(); + } + + [Fact] + public void Should_not_throw_when_func_is_set_using_context() + { + Action configure = () => new ResultTtl((context, result) => new Ttl()); + + configure.ShouldNotThrow(); + } + + [Fact] + public void Should_return_func_result() + { + TimeSpan ttl = TimeSpan.FromMinutes(1); + Func func = (result) => { return new Ttl(result.Ttl); }; + + ResultTtl ttlStrategy = new ResultTtl(func); + + Ttl retrieved = ttlStrategy.GetTtl(new Context("someExecutionKey"), new { Ttl = ttl }); + retrieved.Timespan.Should().Be(ttl); + retrieved.SlidingExpiration.Should().BeFalse(); + } + + [Fact] + public void Should_return_func_result_using_context() + { + const string specialKey = "specialKey"; + + TimeSpan ttl = TimeSpan.FromMinutes(1); + Func func = (context, result) => { return context.ExecutionKey == specialKey ? new Ttl(TimeSpan.Zero) : new Ttl(result.Ttl); }; + + ResultTtl ttlStrategy = new ResultTtl(func); + + ttlStrategy.GetTtl(new Context("someExecutionKey"), new { Ttl = ttl }).Timespan.Should().Be(ttl); + ttlStrategy.GetTtl(new Context(specialKey), new { Ttl = ttl }).Timespan.Should().Be(TimeSpan.Zero); + } + } +} diff --git a/src/Polly.SharedSpecs/Caching/SlidingTtlSpecs.cs b/src/Polly.SharedSpecs/Caching/SlidingTtlSpecs.cs index 2bcdb5ef067..933515e64ee 100644 --- a/src/Polly.SharedSpecs/Caching/SlidingTtlSpecs.cs +++ b/src/Polly.SharedSpecs/Caching/SlidingTtlSpecs.cs @@ -40,7 +40,7 @@ public void Should_return_configured_timespan() SlidingTtl ttlStrategy = new SlidingTtl(ttl); - Ttl retrieved = ttlStrategy.GetTtl(new Context("someExecutionKey")); + Ttl retrieved = ttlStrategy.GetTtl(new Context("someExecutionKey"), null); retrieved.Timespan.Should().Be(ttl); retrieved.SlidingExpiration.Should().BeTrue(); } diff --git a/src/Polly.SharedSpecs/Polly.SharedSpecs.projitems b/src/Polly.SharedSpecs/Polly.SharedSpecs.projitems index 60e28f62efb..0f222d2d401 100644 --- a/src/Polly.SharedSpecs/Polly.SharedSpecs.projitems +++ b/src/Polly.SharedSpecs/Polly.SharedSpecs.projitems @@ -25,6 +25,7 @@ + diff --git a/src/Polly.nuspec b/src/Polly.nuspec index 23d3948c54d..228652d884f 100644 --- a/src/Polly.nuspec +++ b/src/Polly.nuspec @@ -15,6 +15,12 @@ v5.0 is a major release with significant new resilience policies: Timeout; Bulkhead Isolation; Fallback; Cache; and PolicyWrap. See release notes back to v5.0.0 for full details. + 5.7.0 + --------------------- + - Minor cache fixes + - Add ability to calculate cache Ttl based on item to cache + - Allow user-created custom policies + 5.6.1 --------------------- - Extend PolicyWrap syntax with interfaces