private static AsyncCachePolicy <JsonDocument> GetDefaultCachePolicy(IServiceProvider serviceProvider)
 => Policy.CacheAsync(
     serviceProvider
     .GetRequiredService <IAsyncCacheProvider>()
     .AsyncFor <JsonDocument>(),
     // TODO: get from config / from the target service
     TimeSpan.FromHours(24),
     (ctx, key, e) => Logger.Error(e, "JsonDocument cache error for key {Key}", key));
Пример #2
0
 private CachePolicy <HttpResponseMessage> CreateCachePolicy(MemoryCacheProvider provider)
 {
     return(Policy
            .CacheAsync(
                provider.AsyncFor <HttpResponseMessage>(),
                new ResultTtl <HttpResponseMessage>(message => new Ttl(message.Headers.CacheControl.MaxAge ?? TimeSpan.FromHours(24)))
                ));
 }
        public override IAsyncPolicy GetAsyncPolicy(CallContextBase context, CacheAttribute attribute)
        {
            var methodInfo       = context.Method;
            var cacheKeyStrategy = GetCacheKeyStrategy(methodInfo, attribute);
            var ttlStrategy      = GetTimeToLiveStrategy(methodInfo, attribute);

            return(Policy.CacheAsync(_asyncCacheProvider, ttlStrategy, cacheKeyStrategy, OnCacheGet, OnCacheMiss, OnCachePut, OnCacheGetError, OnCachePutError));
        }
        public void Should_throw_when_cache_key_strategy_is_null()
        {
            IAsyncCacheProvider    cacheProvider    = new StubCacheProvider();
            Func <Context, string> cacheKeyStrategy = null;
            Action action = () => Policy.CacheAsync <ResultPrimitive>(cacheProvider, TimeSpan.MaxValue, cacheKeyStrategy);

            action.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("cacheKeyStrategy");
        }
        public void Should_throw_when_ttl_strategy_is_null()
        {
            IAsyncCacheProvider cacheProvider = new StubCacheProvider();
            ITtlStrategy        ttlStrategy   = null;
            Action action = () => Policy.CacheAsync <ResultPrimitive>(cacheProvider, ttlStrategy);

            action.Should().Throw <ArgumentNullException>().And.ParamName.Should().Be("ttlStrategy");
        }
Пример #6
0
        public (IAsyncCacheProvider <TResult>, IAsyncPolicy <TResult>) CreateAsyncCachePolicy <TCache, TResult>()
        {
            IMemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions());
            IAsyncCacheProvider <TResult> provider = new MemoryCacheProvider(memoryCache).AsyncFor <TResult>();

            var policy = Policy.CacheAsync <TResult>(provider, TimeSpan.FromHours(1));

            return(provider, policy);
        }
Пример #7
0
 /// <inheritdoc />
 public CachingCallsWrapper(ICachingStrategy cachingStrategy, IRemovableAsyncCacheProvider asyncCacheProvider)
 {
     _cacheKeys          = new ConcurrentDictionary <string, object>();
     _asyncCacheProvider = asyncCacheProvider;
     _cachingStrategy    = cachingStrategy;
     _retryPolicy        = Policy
                           .CacheAsync(_asyncCacheProvider,
                                       new ContextualTtl());
 }
Пример #8
0
        public void Should_throw_informative_exception_when_sync_execute_on_an_async_policy()
        {
            IAsyncCacheProvider cacheProvider = new StubCacheProvider();

            var cachePolicy = Policy.CacheAsync(cacheProvider, TimeSpan.FromMinutes(5));

            Action action = () => cachePolicy.Execute(() => 0);

            action.ShouldThrow <InvalidOperationException>();
        }
        public AuthenticationApiClientCachingDecorator(IAuthenticationApiClient inner)
        {
            _inner = inner;
            _accessTokenResponseCachePolicy = Policy.CacheAsync(
                _memoryCacheProvider.AsyncFor <AccessTokenResponse>(),
                new ResultTtl <AccessTokenResponse>(r => new Ttl(_expiresIn(r), false)));

            _userInfoCachePolicy = Policy.CacheAsync(
                _memoryCacheProvider.AsyncFor <UserInfo>(),
                new ContextualTtl());
        }
 private IAsyncPolicy GetContextualAsyncPolicy()
 {
     return(Policy.CacheAsync(
                memoryCacheProvider,
                new ContextualTtl(),
                new DefaultCacheKeyStrategy(),
                onCachePut: (context, key) => logger.Trace($"Caching '{key}'."),
                onCacheGet: (context, key) => logger.Trace($"Retrieving '{key}' from the cache."),
                onCachePutError: (context, key, exception) => logger.ErrorJustLogIt($"Cannot add '{key}' to the cache.", exception),
                onCacheGetError: (context, key, exception) => logger.ErrorJustLogIt($"Cannot retrieve '{key}' from the cache.", exception),
                onCacheMiss: (context, key) => logger.Trace($"Cache miss for '{key}'.")));
 }
Пример #11
0
 public void Register()
 {
     if (!registry.ContainsKey(Name))
     {
         var policy = Policy.CacheAsync <CacheFormat>(cacheProvider, TtlStrategy, this,
                                                      OnCacheGet, OnCacheMiss, OnCachePut, OnCacheGetError, OnCachePutError);
         registry.Add(Name, policy);
     }
     else
     {
         logger.LogError("CacheManagement {cacheName} has already been registered", Name);
     }
 }
Пример #12
0
        public void ConfigureServices(ConfigurationServices configurationServices)
        {
            var keyPrefix = Environment.GetEnvironmentVariable("APP_NAME") ?? configurationServices.Environment.ApplicationName;

            configurationServices.Services.AddSingleton(sp => new CacheSyncManager(sp.GetRequiredService <ILogger <CacheSyncManager> >()));
            configurationServices.Services.AddTransient <ICache>(sp =>
            {
                var cache            = sp.GetRequiredService <IDistributedCache>();
                var cacheSyncManager = sp.GetRequiredService <CacheSyncManager>();
                var policy           = Policy.CacheAsync(cache.AsAsyncCacheProvider <byte[]>(), new ContextualTtl());
                return(new Cache(cache, cacheSyncManager, policy, keyPrefix));
            });
        }
Пример #13
0
        public override void Configure(IFunctionsHostBuilder builder)
        {
            var serializerSettings = new JsonSerializerSettings();

            builder.Services.AddStackExchangeRedisCache(options => {
                options.Configuration = Environment.GetEnvironmentVariable("REDIS_CACHE");
                options.InstanceName  = "Eaglesong";
            });

            builder.Services.AddSingleton <Polly.Caching.IAsyncCacheProvider <HttpResponseMessage> >(sp =>
                                                                                                     sp.GetRequiredService <IDistributedCache>()
                                                                                                     .AsAsyncCacheProvider <string>()
                                                                                                     .WithSerializer <HttpResponseMessage, string>(
                                                                                                         new JsonSerializer <HttpResponseMessage>(serializerSettings)
                                                                                                         )
                                                                                                     );
            builder.Services.AddSingleton <Polly.Caching.IAsyncCacheProvider <Profile> >(sp =>
                                                                                         sp.GetRequiredService <IDistributedCache>()
                                                                                         .AsAsyncCacheProvider <string>()
                                                                                         .WithSerializer <Profile, string>(
                                                                                             new JsonSerializer <Profile>(serializerSettings)
                                                                                             )
                                                                                         );
            builder.Services.AddSingleton <Polly.Caching.IAsyncCacheProvider <Details> >(sp =>
                                                                                         sp.GetRequiredService <IDistributedCache>()
                                                                                         .AsAsyncCacheProvider <string>()
                                                                                         .WithSerializer <Details, string>(
                                                                                             new JsonSerializer <Details>(serializerSettings)
                                                                                             )
                                                                                         );

            builder.Services.AddSingleton <IReadOnlyPolicyRegistry <string>, PolicyRegistry>((sp) =>
            {
                var registry = new PolicyRegistry();
                {
                    var provider = sp.GetRequiredService <IAsyncCacheProvider <HttpResponseMessage> >();
                    var policy   = Policy.CacheAsync(provider, TimeSpan.FromMinutes(60));
                    registry.Add("WindrunaPolicy", policy);
                }
                return(registry);
            });

            builder.Services.AddHttpClient("Windrun", client =>
            {
                client.BaseAddress = new Uri("https://windrun.io/api/");
            })
            .AddPolicyHandlerFromRegistry("WindrunaPolicy");

            builder.Services.AddSingleton <IPlayerService, PlayerService>();
        }
Пример #14
0
        public async Task Should_execute_delegate_but_not_put_value_in_cache_if_cache_does_not_hold_value_but_ttl_indicates_not_worth_caching()
        {
            const string valueToReturn = "valueToReturn";
            const string operationKey  = "SomeOperationKey";

            IAsyncCacheProvider stubCacheProvider = new StubCacheProvider();
            CachePolicy         cache             = Policy.CacheAsync(stubCacheProvider, TimeSpan.Zero);

            ((string)await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false).ConfigureAwait(false)).Should().Be(null);

            (await cache.ExecuteAsync(async ctx => { await TaskHelper.EmptyTask.ConfigureAwait(false); return(valueToReturn); }, new Context(operationKey)).ConfigureAwait(false)).Should().Be(valueToReturn);

            ((string)await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false).ConfigureAwait(false)).Should().Be(null);
        }
Пример #15
0
        public async Task Should_execute_delegate_and_put_value_in_cache_if_cache_does_not_hold_value()
        {
            const string valueToReturn = "valueToReturn";
            const string executionKey  = "SomeExecutionKey";

            IAsyncCacheProvider stubCacheProvider = new StubCacheProvider();
            CachePolicy         cache             = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue);

            ((string)await stubCacheProvider.GetAsync(executionKey, CancellationToken.None, false).ConfigureAwait(false)).Should().BeNull();

            (await cache.ExecuteAsync(async() => { await TaskHelper.EmptyTask.ConfigureAwait(false); return(valueToReturn); }, new Context(executionKey)).ConfigureAwait(false)).Should().Be(valueToReturn);

            ((string)await stubCacheProvider.GetAsync(executionKey, CancellationToken.None, false).ConfigureAwait(false)).Should().Be(valueToReturn);
        }
        public async Task Should_execute_delegate_and_put_value_in_cache_but_when_it_expires_execute_delegate_again()
        {
            const string valueToReturn = "valueToReturn";
            const string operationKey  = "SomeOperationKey";

            IAsyncCacheProvider stubCacheProvider = new StubCacheProvider();
            TimeSpan            ttl = TimeSpan.FromMinutes(30);
            var cache = Policy.CacheAsync <string>(stubCacheProvider, ttl);

            (bool cacheHit1, object fromCache1) = await stubCacheProvider.TryGetAsync(operationKey, CancellationToken.None, false).ConfigureAwait(false);

            cacheHit1.Should().BeFalse();
            fromCache1.Should().BeNull();

            int delegateInvocations             = 0;
            Func <Context, Task <string> > func = async ctx =>
            {
                delegateInvocations++;
                await TaskHelper.EmptyTask.ConfigureAwait(false);

                return(valueToReturn);
            };

            DateTimeOffset fixedTime = SystemClock.DateTimeOffsetUtcNow();

            SystemClock.DateTimeOffsetUtcNow = () => fixedTime;

            // First execution should execute delegate and put result in the cache.
            (await cache.ExecuteAsync(func, new Context(operationKey)).ConfigureAwait(false)).Should().Be(valueToReturn);
            delegateInvocations.Should().Be(1);

            (bool cacheHit2, object fromCache2) = await stubCacheProvider.TryGetAsync(operationKey, CancellationToken.None, false).ConfigureAwait(false);

            cacheHit2.Should().BeTrue();
            fromCache2.Should().Be(valueToReturn);

            // Second execution (before cache expires) should get it from the cache - no further delegate execution.
            // (Manipulate time so just prior cache expiry).
            SystemClock.DateTimeOffsetUtcNow = () => fixedTime.Add(ttl).AddSeconds(-1);
            (await cache.ExecuteAsync(func, new Context(operationKey)).ConfigureAwait(false)).Should().Be(valueToReturn);
            delegateInvocations.Should().Be(1);

            // Manipulate time to force cache expiry.
            SystemClock.DateTimeOffsetUtcNow = () => fixedTime.Add(ttl).AddSeconds(1);

            // Third execution (cache expired) should not get it from the cache - should cause further delegate execution.
            (await cache.ExecuteAsync(func, new Context(operationKey)).ConfigureAwait(false)).Should().Be(valueToReturn);
            delegateInvocations.Should().Be(2);
        }
Пример #17
0
        /// <summary>
        /// Generates a Polly <see cref="CachePolicy{HttpResponseMessage}"/> from the configuration.
        /// </summary>
        /// <param name="logger">The <see cref="ILogger"/> instance to use for logging.</param>
        /// <returns>A <see cref="CachePolicy{HttpResponseMessage}"/> instance.</returns>
        /// <remarks>
        /// Currently only supports in-memory cache.
        /// Operation key set on the context is used as the cache key.
        /// </remarks>
        public IAsyncPolicy <HttpResponseMessage> AsTypeModel(ILogger logger)
        {
            _ = logger ?? throw new ArgumentNullException(nameof(logger));

            if (Time is null || TimeSpan.Equals(Time.AsTimeSpan(), TimeSpan.Zero))
            {
                logger.LogCritical("{PolicyConfig} : {Property} must be a valid time span", nameof(CacheConfig), "time");
                throw new InvalidOperationException("time must be a valid time span");
            }

            // Create delegates
            void OnCacheGet(Context context, string key) =>
            logger.LogInformation("{PolicyKey} at {OperationKey}: Retrieving {Key} from cache",
                                  context.PolicyKey, context.OperationKey, key);

            void OnCacheMiss(Context context, string key) =>
            logger.LogInformation("{PolicyKey} at {OperationKey}: {Key} was not present in cache",
                                  context.PolicyKey, context.OperationKey, key);

            void OnCachePut(Context context, string key) =>
            logger.LogInformation("{PolicyKey} at {OperationKey}: Inserting {Key} into cache",
                                  context.PolicyKey, context.OperationKey, key);

            void OnCacheGetError(Context context, string key, Exception exception) =>
            logger.LogError(exception, "{PolicyKey} at {OperationKey}: Error retrieving {Key} from cache",
                            context.PolicyKey, context.OperationKey, key);

            void OnCachePutError(Context context, string key, Exception exception) =>
            logger.LogError(exception, "{PolicyKey} at {OperationKey}: Error inserting {Key} into cache",
                            context.PolicyKey, context.OperationKey, key);

            if (!Absolute)
            {
                // Cache strategy if it is purely time span based
                strategy = CreateStrategy();
            }

            // Create policy with default cache key strategy
            var cache = Policy
                        .CacheAsync(cacheProvider,
                                    ttlStrategy: new ResultTtl <HttpResponseMessage>(CacheOKResponse),
                                    onCacheGet: OnCacheGet,
                                    onCacheMiss: OnCacheMiss,
                                    onCachePut: OnCachePut,
                                    onCacheGetError: OnCacheGetError,
                                    onCachePutError: OnCachePutError);

            return(cache);
        }
Пример #18
0
        public void Should_always_execute_delegate_if_execution_is_void_returning()
        {
            string executionKey = Guid.NewGuid().ToString();

            CachePolicy cache = Policy.CacheAsync(new StubCacheProvider(), TimeSpan.MaxValue);

            int         delegateInvocations = 0;
            Func <Task> action = async() => { delegateInvocations++; await TaskHelper.EmptyTask.ConfigureAwait(false); };

            cache.ExecuteAsync(action, new Context(executionKey));
            delegateInvocations.Should().Be(1);

            cache.ExecuteAsync(action, new Context(executionKey));
            delegateInvocations.Should().Be(2);
        }
        public void CacheHit()
        {
            var cache         = new Mock <IDistributedCache>(MockBehavior.Strict);
            var cacheProvider = new Mock <IAsyncCacheProvider>(MockBehavior.Strict);
            var cachePolicy   = Policy.CacheAsync(cacheProvider.Object, new Mock <ITtlStrategy>().Object);
            var repository    = new Mock <ISecretRepository>(MockBehavior.Strict);
            var service       = new SecretRepositoryCache(repository.Object, cachePolicy);

            // NB Have to use the underlying methods not the helpful extensions
            cache.Setup(x => x.Get("clientsecret:A")).Returns(Encoding.UTF8.GetBytes("B"));

            var candidate = service.ClientSecret("A");

            Assert.That(candidate, Is.EqualTo("B"), "Secret differs");
        }
Пример #20
0
        public static void GetPolicyRegistry(IAsyncCacheProvider cacheProvider,
                                             IPolicyRegistry <string> registry)
        {
            registry.Add("thriceTriplingRetryPolicy", Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode)
                         .Or <TimeoutRejectedException>()
                         .WaitAndRetryAsync(thriceTriplingTimeSpans));
            registry.Add("loginResponseRetryPolicy", Policy.HandleResult <LoginResponse>(lr => lr.LoginStatus != _successfulLoginStatus)
                         .Or <TimeoutRejectedException>()
                         .WaitAndRetryAsync(thriceTriplingTimeSpans));
            registry.Add("thirtySecondTimeoutPolicy", Policy.TimeoutAsync(TimeSpan.FromSeconds(30)));

            AsyncCachePolicy <LoginResponse> cachePolicy = Policy.CacheAsync <LoginResponse>(cacheProvider, _timeToLive);

            registry.Add("oneMinuteLoginCachePolicy", cachePolicy);
        }
Пример #21
0
        internal AccessTokenService(string clientId, string clientSecret, IHttpRequestSender requestSender)
        {
            _clientId      = clientId;
            _clientSecret  = clientSecret;
            _requestSender = requestSender;

            _cache       = new MemoryCache(new MemoryCacheOptions());
            _cachePolicy = Policy.CacheAsync(
                new MemoryCacheProvider(_cache).AsyncFor <AccessToken>(),
                new ResultTtl <AccessToken>(t => new Ttl(t.LifeTime - TimeSpan.FromHours(1))),
                onCacheError: (ctx, _, ex) =>
            {
                Logger.ErrorException($"Could not retrieve access token: '{ex.Message}'", ex);
            });
        }
Пример #22
0
        public void Should_always_execute_delegate_if_execution_is_void_returning()
        {
            string operationKey = "SomeKey";

            var cache = Policy.CacheAsync(new StubCacheProvider(), TimeSpan.MaxValue);

            int delegateInvocations     = 0;
            Func <Context, Task> action = async _ => { delegateInvocations++; await TaskHelper.EmptyTask; };

            cache.ExecuteAsync(action, new Context(operationKey));
            delegateInvocations.Should().Be(1);

            cache.ExecuteAsync(action, new Context(operationKey));
            delegateInvocations.Should().Be(2);
        }
Пример #23
0
        public async Task CanCacheApiResult()
        {
            var memoryCache         = new MemoryCache(new MemoryCacheOptions());
            var memoryCacheProvider = new MemoryCacheProvider(memoryCache);
            var cachePolicy         = Policy.CacheAsync(memoryCacheProvider, TimeSpan.FromMinutes(5));

            // typically cache key would be dynamically generated to be unique per unique request (same for equivalent requests)
            var result = await cachePolicy.ExecuteAsync((ctx) => DemoHelper.DemoClient.GetStringAsync("api/demo/cache"), new Context("MyKey"));

            var result2 = await cachePolicy.ExecuteAsync((ctx) => DemoHelper.DemoClient.GetStringAsync("api/demo/cache"), new Context("MyKey"));

            var result3 = await cachePolicy.ExecuteAsync((ctx) => DemoHelper.DemoClient.GetStringAsync("api/demo/cache"), new Context("MyKey2"));

            Assert.AreEqual(result, result2);
            Assert.AreNotEqual(result, result3);
        }
Пример #24
0
        //[Test]
        public async Task Foo()
        {
            var count1 = 0;
            var count2 = 0;
            var count3 = 0;

            var services = new ServiceCollection();

            services.AddMemoryCache()
            .AddSingleton <Caching.IAsyncCacheProvider, MemoryCacheProvider>()
            .AddSingleton <Func <int, Task <Dto> > >(_ =>
            {
                count1++;
                return(Task.FromResult(new Dto()));
            })
            .AddSingleton <Func <Task <Dto> > >(() =>
            {
                count2++;
                return(Task.FromResult(new Dto()));
            })
            .AddSingleton <Func <int, Task <string> > >(_ =>
            {
                count3++;
                return(Task.FromResult(Guid.NewGuid().ToString()));
            })
            .AddSingleton(typeof(IService <,>), typeof(DelegatingService <,>));
            // .Decorate<>();

            var provider = services.BuildServiceProvider();

            var policy = Policy.CacheAsync(provider.GetService <Caching.IAsyncCacheProvider>(), TimeSpan.MaxValue);

            var service = provider.GetRequiredService <IService <int, Dto> >();

            service = service.InterceptWithPolicy(policy);

            // Act
            var result11 = await service.GetAsync(-1);

            var result12 = await service.GetAsync(-1);

            // Assert
            Assert.AreEqual(1, count1);
            Assert.AreEqual(result11, result12);
            Assert.DoesNotThrow(() => Guid.Parse(result11.Str));
        }
Пример #25
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IMemoryCache memoryCache)
        {
            Polly.Caching.MemoryCache.MemoryCacheProvider memoryCacheProvider
                = new Polly.Caching.MemoryCache.MemoryCacheProvider(memoryCache);

            CachePolicy <HttpResponseMessage> cachePolicy =
                Policy.CacheAsync <HttpResponseMessage>(memoryCacheProvider, TimeSpan.FromMinutes(5));

            _myPolicyRegistry.Add("myPollyCache", cachePolicy);

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
        }
        public void CacheMiss()
        {
            var cache         = new Mock <IDistributedCache>(MockBehavior.Strict);
            var cacheProvider = new Mock <IAsyncCacheProvider>(MockBehavior.Strict);
            var cachePolicy   = Policy.CacheAsync(cacheProvider.Object, new Mock <ITtlStrategy>().Object);
            var repository    = new Mock <ISecretRepository>(MockBehavior.Strict);
            var service       = new SecretRepositoryCache(repository.Object, cachePolicy);

            // NB Have to use the underlying methods not the helpful extensions
            cache.Setup(x => x.Get("clientsecret:A")).Returns((byte[])null);
            cache.Setup(x => x.Set("clientsecret:A", It.IsAny <byte[]>(), It.IsAny <DistributedCacheEntryOptions>()));

            repository.Setup(x => x.ClientSecret("A")).Returns("B");

            var candidate = service.ClientSecret("A");

            Assert.That(candidate, Is.EqualTo("B"), "Secret differs");
        }
Пример #27
0
        public async Task Should_execute_delegate_and_put_value_in_cache_for_non_nullable_types_if_cache_does_not_hold_value()
        {
            const ResultPrimitive valueToReturn = ResultPrimitive.Substitute;
            const string          operationKey  = "SomeOperationKey";

            IAsyncCacheProvider stubCacheProvider = new StubCacheProvider();
            CachePolicy         cache             = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue);

            (await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false)).Should().BeNull();

            (await cache.ExecuteAsync(async ctx =>
            {
                await TaskHelper.EmptyTask.ConfigureAwait(false);
                return(ResultPrimitive.Substitute);
            }, new Context(operationKey))).Should().Be(valueToReturn);

            (await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false)).Should().Be(valueToReturn);
        }
Пример #28
0
        public static AsyncPolicyWrap <HttpResponseMessage> GetRequestPolicy(IMemoryCache memoryCache = null, int cacheSeconds = 0, int additionalRetries = 0, int requestTimeoutSeconds = 100)
        {
            AsyncCachePolicy cache = null;

            if (memoryCache != null)
            {
                var memoryCacheProvider = new MemoryCacheProvider(memoryCache);
                cache = Policy.CacheAsync(memoryCacheProvider, TimeSpan.FromSeconds(cacheSeconds));
            }

            int[] httpStatusCodesWorthRetrying =
            {
                StatusCodes.Status408RequestTimeout,
                StatusCodes.Status429TooManyRequests,
                //StatusCodes.Status500InternalServerError,
                StatusCodes.Status502BadGateway,
                StatusCodes.Status503ServiceUnavailable,
                StatusCodes.Status504GatewayTimeout
            };

            var waitAndRetryPolicy = Policy
                                     .Handle <HttpRequestException>() //HttpClient Timeout or CancellationToken
                                     .Or <TimeoutRejectedException>()
                                     .OrResult <HttpResponseMessage>(r => httpStatusCodesWorthRetrying.Contains((int)r.StatusCode))
                                     .WaitAndRetryAsync(additionalRetries,
                                                        retryAttempt => TimeSpan.FromSeconds(1));

            //https://github.com/App-vNext/Polly/wiki/Timeout
            var requestTimeout = Policy.TimeoutAsync(TimeSpan.FromSeconds(requestTimeoutSeconds));

            //https://github.com/App-vNext/Polly/wiki/PolicyWrap
            AsyncPolicyWrap <HttpResponseMessage> policyWrap = null;

            if (cache != null)
            {
                policyWrap = cache.WrapAsync(waitAndRetryPolicy).WrapAsync(requestTimeout);
            }
            else
            {
                policyWrap = waitAndRetryPolicy.WrapAsync(requestTimeout);
            }

            return(policyWrap);
        }
Пример #29
0
        public NewCombinedFeedSource(IEnumerable <IAmACommunityMember> tamarins)
        {
            EnsureHttpClient();

            Tamarins = tamarins;

            if (retryPolicy == null)
            {
                // cache in memory for an hour
                var memoryCache         = new MemoryCache(new MemoryCacheOptions());
                var memoryCacheProvider = new MemoryCacheProvider(memoryCache);
                cachePolicy = Policy.CacheAsync(memoryCacheProvider, TimeSpan.FromHours(1), OnCacheError);

                // retry policy with max 2 retries, delay by x*x^1.2 where x is retry attempt
                // this will ensure we don't retry too quickly
                retryPolicy = Policy.Handle <FeedReadFailedException>()
                              .WaitAndRetryAsync(2, retry => TimeSpan.FromSeconds(retry * Math.Pow(1.2, retry)));
            }
        }
Пример #30
0
        public async Task Should_not_error_for_executions_on_non_nullable_types_if_cache_does_not_hold_value()
        {
            const string operationKey = "SomeOperationKey";

            bool onErrorCalled = false;
            Action <Context, string, Exception> onError = (ctx, key, exc) => { onErrorCalled = true; };

            IAsyncCacheProvider stubCacheProvider = new StubCacheProvider();
            CachePolicy         cache             = Policy.CacheAsync(stubCacheProvider, TimeSpan.MaxValue, onError);

            (await stubCacheProvider.GetAsync(operationKey, CancellationToken.None, false)).Should().BeNull();
            ResultPrimitive result = await cache.ExecuteAsync(async ctx =>
            {
                await TaskHelper.EmptyTask.ConfigureAwait(false);
                return(ResultPrimitive.Substitute);
            }, new Context(operationKey));

            onErrorCalled.Should().BeFalse();
        }