// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { IPolicyRegistry <string> registry = services.AddPolicyRegistry(); IAsyncPolicy <HttpResponseMessage> httpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .RetryAsync(3); registry.Add("SimpleHttpRetryPolicy", httpRetryPolicy); IAsyncPolicy <HttpResponseMessage> httWaitAndpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt)); registry.Add("SimpleWaitAndRetryPolicy", httWaitAndpRetryPolicy); IAsyncPolicy <HttpResponseMessage> noOpPolicy = Policy.NoOpAsync() .AsAsyncPolicy <HttpResponseMessage>(); registry.Add("NoOpPolicy", noOpPolicy); services.AddHttpClient("RemoteServer", client => { client.BaseAddress = new Uri("http://localhost:57696/api/"); client.DefaultRequestHeaders.Add("Accept", "application/json"); }).AddPolicyHandlerFromRegistry((PolicySelector)); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }
public DurableCircuitBreakerClient( IPolicyRegistry <string> policyRegistry, IServiceProvider serviceProvider) { this.policyRegistry = policyRegistry; this.serviceProvider = serviceProvider; }
private void ConfigurePolicies(IServiceCollection services) { policyRegistry = services.AddPolicyRegistry(); var timeoutPolicy = Policy.TimeoutAsync <HttpResponseMessage>(TimeSpan.FromMilliseconds(1500)); policyRegistry.Add("timeout", timeoutPolicy); }
public CacheManagement(ILogger logger, IPolicyRegistry <string> registry, IAsyncCacheProvider cacheProvider, IMemoryCacheExtended cache) { this.logger = logger; this.registry = registry; this.cacheProvider = cacheProvider.AsyncFor <CacheFormat>(); this.cache = cache; }
public static IServiceCollection AddPolicies( this IServiceCollection services, IPolicyRegistry <string> policyRegistry, string retryPolicyKey, PolicyOptions policyOptions) { if (policyRegistry == null || policyOptions == null) { return(services); } policyRegistry.Add( retryPolicyKey, HttpPolicyExtensions .HandleTransientHttpError() .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.TooManyRequests) .OrResult(msg => msg?.Headers?.RetryAfter != null) .WaitAndRetryAsync( policyOptions.HttpRetry.Count, retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(policyOptions.HttpRetry.BackoffPower, retryAttempt) * policyOptions.HttpRetry.BackOffBaseMilliseconds))); return(services); }
public static IServiceCollection AddPolicies( this IServiceCollection services, IPolicyRegistry <string> policyRegistry, string keyPrefix, PolicyOptions policyOptions) { _ = policyOptions ?? throw new ArgumentNullException(nameof(policyOptions)); policyRegistry?.Add( $"{keyPrefix}_{nameof(PolicyOptions.HttpRetry)}", HttpPolicyExtensions .HandleTransientHttpError() .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.TooManyRequests) .OrResult(r => r?.Headers?.RetryAfter != null) .WaitAndRetryAsync( policyOptions.HttpRetry.Count, retryAttempt => TimeSpan.FromSeconds(Math.Pow(policyOptions.HttpRetry.BackoffPower, retryAttempt)))); policyRegistry?.Add( $"{keyPrefix}_{nameof(PolicyOptions.HttpCircuitBreaker)}", HttpPolicyExtensions .HandleTransientHttpError() .CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: policyOptions.HttpCircuitBreaker.ExceptionsAllowedBeforeBreaking, durationOfBreak: policyOptions.HttpCircuitBreaker.DurationOfBreak)); return(services); }
private static IServiceCollection ConfigurePolicies(this IServiceCollection services) { IPolicyRegistry <string> registry = services.AddPolicyRegistry(); IAsyncPolicy <HttpResponseMessage> httpWaitAndpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) / 2), onRetry: (httpResponseMessage, retryCount) => { // Log Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"Request failed...{httpResponseMessage.Result.StatusCode}"); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"Retrying..."); Console.ForegroundColor = ConsoleColor.White; }); registry.Add(nameof(httpWaitAndpRetryPolicy), httpWaitAndpRetryPolicy); IAsyncPolicy <HttpResponseMessage> noOpPolicy = Policy.NoOpAsync() .AsAsyncPolicy <HttpResponseMessage>(); registry.Add(nameof(noOpPolicy), noOpPolicy); return(services); }
public static void AddPolicies(this IServiceCollection services) { IPolicyRegistry <string> registry = services.AddPolicyRegistry(); Random jitterer = new Random(); var policyGSync = Policy.Handle <Exception>(ex => !(ex is GoogleApiException || ex is NegocioException)) .WaitAndRetryAsync(3, // exponential back-off plus some jitter retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)) + TimeSpan.FromMilliseconds(jitterer.Next(0, 30))); registry.Add(PoliticaPolly.PolicyGoogleSync, policyGSync); var policyFilas = Policy.Handle <Exception>() .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(5)); registry.Add(PoliticaPolly.PolicyPublicaFila, policyFilas); var policyGSyncRemocaoProfessor = Policy.Handle <Exception>() .WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(60) }, (exception, timeSpan, retryCount, context) => { Console.WriteLine($"RETRY policyGSyncRemocaoProfessor - {retryCount}: {exception.Message}"); }); //.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(30)); registry.Add(PoliticaPolly.PolicyRemocaoProfessor, policyGSyncRemocaoProfessor); RegistrarPolicyGsa(registry); }
private static void RegistrarPolicyGsa(IPolicyRegistry <string> registry) { var policy = Policy.Handle <Exception>() .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(60)); registry.Add(PoliticaPolly.PolicyCargaGsa, policy); }
/// <summary> /// Add chaos-injection policies to every policy returning <see cref="IAsyncPolicy{HttpResponseMessage}"/> /// in the supplied <paramref name="registry"/> /// </summary> /// <param name="registry">The <see cref="IPolicyRegistry{String}"/> whose policies should be decorated with chaos policies.</param> /// <returns>The policy registry.</returns> public static IPolicyRegistry <string> AddChaosInjectors(this IPolicyRegistry <string> registry) { foreach (KeyValuePair <string, IsPolicy> policyEntry in registry) { if (policyEntry.Value is IAsyncPolicy <HttpResponseMessage> policy) { registry[policyEntry.Key] = policy .WrapAsync(MonkeyPolicy.InjectFaultAsync <HttpResponseMessage>( (ctx, ct) => GetException(ctx, ct), GetInjectionRate, GetEnabled)) .WrapAsync(MonkeyPolicy.InjectFaultAsync <HttpResponseMessage>( (ctx, ct) => GetHttpResponseMessage(ctx, ct), GetInjectionRate, GetHttpResponseEnabled)) .WrapAsync(MonkeyPolicy.InjectLatencyAsync <HttpResponseMessage>( GetLatency, GetInjectionRate, GetEnabled)) ; } } return(registry); }
public ProjectsController(IHttpClientFactory clientFactory, IPolicyRegistry <string> policyRegistry) { this.clientFactory = clientFactory; this.policyRegistry = policyRegistry; //this.cachePolicy = policyRegistry.Get<AsyncCachePolicy<HttpResponseMessage>>(PolicyNames.CachePolicy); this.cachePolicy = policyRegistry.Get <AsyncCachePolicy <HttpResponseMessage> >(PolicyNames.CacheOnlyOkPolicy); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddSingleton(GetRegistry()); IAsyncPolicy <HttpResponseMessage> httpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .RetryAsync(3); IAsyncPolicy <HttpResponseMessage> noPolicy = Policy.NoOpAsync <HttpResponseMessage>(); // Polly Single Policy //services.AddHttpClient("RemoteServer", client => //{ // client.BaseAddress = new Uri("https://localhost:44363/"); // client.DefaultRequestHeaders.Add("Accept", "application/json"); //}).AddPolicyHandler(httpRetryPolicy); IPolicyRegistry <string> registry = services.AddPolicyRegistry(); registry.Add("SimpleRetry", httpRetryPolicy); registry.Add("NoOp", noPolicy); services.AddHttpClient("RemoteServer", client => { client.BaseAddress = new Uri("https://localhost:44363/"); client.DefaultRequestHeaders.Add("Accept", "application/json"); }).AddPolicyHandlerFromRegistry(PolicySelector); services.AddControllers(); }
public GenericAdapterOutboundHandlerService(IOutboundClient outboundClient, IApplicationMessageFactory messageFactory, IPolicyRegistry <string> policyRegistry) { _tcs = new TaskCompletionSource <Message>(); _outboundClient = outboundClient; _messageFactory = messageFactory; _policyRegistry = policyRegistry; }
/// <summary> /// Adds Polly to the services. /// </summary> /// <param name="services">The <see cref="IServiceCollection"/> to add Polly to.</param> /// <returns> /// The value specified by <paramref name="services"/>. /// </returns> public static IServiceCollection AddPolly(this IServiceCollection services) { var sleepDurations = new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), }; var readPolicy = HttpPolicyExtensions.HandleTransientHttpError() .WaitAndRetryAsync(sleepDurations) .WithPolicyKey("ReadPolicy"); var writePolicy = Policy.NoOpAsync() .AsAsyncPolicy <HttpResponseMessage>() .WithPolicyKey("WritePolicy"); var policies = new[] { readPolicy, writePolicy, }; IPolicyRegistry <string> registry = services.AddPolicyRegistry(); foreach (var policy in policies) { registry.Add(policy.PolicyKey, policy); } return(services); }
public static IPolicyRegistry <string> AddBasicRetryPolicy(this IPolicyRegistry <string> policyRegistry) { var retryPolicy = Policy .Handle <Exception>() .OrResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .WaitAndRetryAsync(3, retryCount => TimeSpan.FromSeconds(Math.Pow(2, retryCount)), (result, timeSpan, retryCount, context) => { if (!context.TryGetLogger(out var logger)) { return; } context.TryGetValue("url", out var url); var telemetry = new TelemetryClient(); if (result.Exception != null) { telemetry.TrackException(new Exception($"An exception occurred on retry {retryCount} for {context.PolicyKey} " + $"on URL {url}")); } else { telemetry.TrackException(new Exception($"A non success code {(int)result.Result.StatusCode} " + $"was received on retry {retryCount} for {context.PolicyKey}. " + $"Will retry in {Math.Pow(2, retryCount)} seconds on URL {url}")); } })
public static IPolicyRegistry <string> AddStandardPolicies( this IPolicyRegistry <string> policyRegistry, string keyPrefix, CorePolicyOptions policyOptions) { if (policyOptions == null) { throw new ArgumentException("policyOptions cannot be null", nameof(policyOptions)); } if (policyRegistry == null) { throw new ArgumentException("policyRegistry cannot be null", nameof(policyRegistry)); } policyRegistry.Add( $"{keyPrefix}_{nameof(CorePolicyOptions.HttpRetry)}", HttpPolicyExtensions .HandleTransientHttpError() .WaitAndRetryAsync( policyOptions.HttpRetry.Count, retryAttempt => TimeSpan.FromSeconds(Math.Pow(policyOptions.HttpRetry.BackoffPower, retryAttempt)))); policyRegistry.Add( $"{keyPrefix}_{nameof(CorePolicyOptions.HttpCircuitBreaker)}", HttpPolicyExtensions .HandleTransientHttpError() .CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: policyOptions.HttpCircuitBreaker.ExceptionsAllowedBeforeBreaking, durationOfBreak: policyOptions.HttpCircuitBreaker.DurationOfBreak)); return(policyRegistry); }
public AuthenticationClientAsync(IConfiguration configuration, HttpClient httpClient, IPolicyRegistry <string> registry) { _url = configuration["BetfairApi:Authentication:Url"]; var userName = configuration["BetfairApi:Authentication:UserName"]; var password = configuration["BetfairApi:Authentication:Password"]; var postData = new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("username", userName), new KeyValuePair <string, string>("password", password) }; _loginBody = new FormUrlEncodedContent(postData); var appKey = configuration["BetfairApi:AppKey"]; var baseUrl = configuration["BetfairApi:Authentication:BaseUrl"]; var appKeyHeader = configuration["BetfairApi:AppKeyHeader"]; var mediaType = configuration["BetfairApi:Authentication:MediaType"]; httpClient.BaseAddress = new Uri(baseUrl); httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Add(appKeyHeader, appKey); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(mediaType)); _httpClient = httpClient; _registry = registry; }
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); IPolicyRegistry <string> registry = services.AddPolicyRegistry(); IAsyncPolicy <HttpResponseMessage> _httpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .Or <TimeoutRejectedException>() .RetryAsync(3); registry.Add("SimpleHttpRetryPolicy", _httpRetryPolicy); IAsyncPolicy <HttpResponseMessage> httpWaitAndRetryPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt)); registry.Add("SimpleWaitAndRetryPolicy", httpWaitAndRetryPolicy); IAsyncPolicy <HttpResponseMessage> noOpPolicy = Policy.NoOpAsync().AsAsyncPolicy <HttpResponseMessage>(); registry.Add("NoOpPolicy", noOpPolicy); services.AddHttpClient(PollyConstants.RemoteServer, client => { client.BaseAddress = new Uri("http://localhost:58042/api/"); client.DefaultRequestHeaders.Add("Accept", "application/json"); }).AddPolicyHandlerFromRegistry(PolicySelector); }
public static IHttpClientBuilder AddLCUHTTPClient <TClient>(this IServiceCollection services, IPolicyRegistry <string> registry, Uri baseAddress, int retryCycles = 3, int retrySleepDurationMilliseconds = 500, int circuitFailuresAllowed = 5, int circuitBreakDurationSeconds = 5) where TClient : class { return(services .AddRefitClient <TClient>(services => { return new RefitSettings() { ContentSerializer = new NewtonsoftJsonContentSerializer() }; }) .ConfigureHttpClient(client => { client.BaseAddress = baseAddress; })); //.AddLCUTimeoutPolicy(registry) //.AddTransientHttpErrorPolicy(p => //{ // return p.WaitAndRetryAsync(retryCycles, _ => // { // return TimeSpan.FromMilliseconds(retrySleepDurationMilliseconds); // }); //}) //.AddTransientHttpErrorPolicy(p => //{ // return p.CircuitBreakerAsync(circuitFailuresAllowed, // TimeSpan.FromSeconds(circuitBreakDurationSeconds)); //}); }
/// <summary> /// Adds the specified <paramref name="policy"/> to the registry using /// the <see cref="IsPolicy.PolicyKey"/>. /// </summary> /// <param name="registry"> /// The <see cref="IPolicyRegistry{String}"/> to add policies to. /// </param> /// <param name="policy">The <see cref="IsPolicy"/> to add.</param> public static void Add(this IPolicyRegistry <string> registry, IsPolicy?policy) { if (registry != null && policy != null) { registry.Add(policy.PolicyKey, policy); } }
public QueryProcessor(IHandlerConfiguration handlerConfiguration, IPolicyRegistry policyRegistry, IRequestContextFactory requestContextFactory) { if (handlerConfiguration == null) { throw new ArgumentNullException(nameof(handlerConfiguration)); } if (policyRegistry == null) { throw new ArgumentNullException(nameof(policyRegistry)); } if (requestContextFactory == null) { throw new ArgumentNullException(nameof(requestContextFactory)); } if (handlerConfiguration.HandlerRegistry == null) { throw new ArgumentException($"{nameof(handlerConfiguration.HandlerRegistry)} must not be null", nameof(handlerConfiguration)); } if (handlerConfiguration.HandlerFactory == null) { throw new ArgumentException($"{nameof(handlerConfiguration.HandlerFactory)} must not be null", nameof(handlerConfiguration)); } if (handlerConfiguration.DecoratorFactory == null) { throw new ArgumentException($"{nameof(handlerConfiguration.DecoratorFactory)} must not be null", nameof(handlerConfiguration)); } _handlerRegistry = handlerConfiguration.HandlerRegistry; _handlerFactory = handlerConfiguration.HandlerFactory; _decoratorFactory = handlerConfiguration.DecoratorFactory; _policyRegistry = policyRegistry; _requestContextFactory = requestContextFactory; }
/// <summary> /// Initializes a new instance of the <see cref="CommandProcessor"/> class. /// Use this constructor when both rpc support is required /// </summary> /// <param name="subscriberRegistry">The subscriber registry.</param> /// <param name="handlerFactory">The handler factory.</param> /// <param name="requestContextFactory">The request context factory.</param> /// <param name="policyRegistry">The policy registry.</param> /// <param name="mapperRegistry">The mapper registry.</param> /// <param name="outBox">The outbox</param> /// <param name="producerRegistry">The register of producers via whom we send messages over the external bus</param> /// <param name="replySubscriptions">The Subscriptions for creating the reply queues</param> /// <param name="responseChannelFactory">If we are expecting a response, then we need a channel to listen on</param> /// <param name="outboxTimeout">How long should we wait to write to the outbox</param> /// <param name="featureSwitchRegistry">The feature switch config provider.</param> /// <param name="inboxConfiguration">Do we want to insert an inbox handler into pipelines without the attribute. Null (default = no), yes = how to configure</param> /// <param name="boxTransactionConnectionProvider">The Box Connection Provider to use when Depositing into the outbox.</param> public CommandProcessor( IAmASubscriberRegistry subscriberRegistry, IAmAHandlerFactory handlerFactory, IAmARequestContextFactory requestContextFactory, IPolicyRegistry <string> policyRegistry, IAmAMessageMapperRegistry mapperRegistry, IAmAnOutbox <Message> outBox, IAmAProducerRegistry producerRegistry, IEnumerable <Subscription> replySubscriptions, int outboxTimeout = 300, IAmAFeatureSwitchRegistry featureSwitchRegistry = null, IAmAChannelFactory responseChannelFactory = null, InboxConfiguration inboxConfiguration = null, IAmABoxTransactionConnectionProvider boxTransactionConnectionProvider = null) : this(subscriberRegistry, handlerFactory, requestContextFactory, policyRegistry) { _mapperRegistry = mapperRegistry; _featureSwitchRegistry = featureSwitchRegistry; _responseChannelFactory = responseChannelFactory; _inboxConfiguration = inboxConfiguration; _boxTransactionConnectionProvider = boxTransactionConnectionProvider; _replySubscriptions = replySubscriptions; InitExtServiceBus(policyRegistry, outBox, outboxTimeout, producerRegistry); ConfigureCallbacks(producerRegistry); }
private static IHttpClientBuilder AddHttpClientWithPolicies <TClient, TImplementation, TClientOptions>( IServiceCollection services, IPolicyRegistry <string> policyRegistry, string retryPolicyKey, string configurationSectionName, PolicyOptions policyOptions, IConfiguration configuration, string httpClientName = null) where TClient : class where TImplementation : class, TClient where TClientOptions : HttpClientOptions, new() { var policies = services .AddPolicies( policyRegistry, retryPolicyKey, policyOptions); if (!string.IsNullOrEmpty(httpClientName)) { return(policies.AddNamedHttpClient <TClient, TImplementation, TClientOptions>( configuration, configurationSectionName, retryPolicyKey, httpClientName)); } return(policies.AddUnnamedHttpClient <TClient, TImplementation, TClientOptions>( configuration, configurationSectionName, retryPolicyKey)); }
//Create an instance of the ExternalBusServices if one not already set for this app. Note that we do not support reinitialization here, so once you have //set a command processor for the app, you can't call init again to set them - although the properties are not read-only so overwriting is possible //if needed as a "get out of gaol" card. private void InitExtServiceBus(IPolicyRegistry <string> policyRegistry, IAmAnOutbox <Message> outbox, int outboxTimeout, IAmAProducerRegistry producerRegistry) { if (_bus == null) { lock (padlock) { if (_bus == null) { if (producerRegistry == null) { throw new ConfigurationException("A producer registry is required to create an external bus"); } _bus = new ExternalBusServices(); if (outbox is IAmAnOutboxSync <Message> syncOutbox) { _bus.OutBox = syncOutbox; } if (outbox is IAmAnOutboxAsync <Message> asyncOutbox) { _bus.AsyncOutbox = asyncOutbox; } _bus.OutboxTimeout = outboxTimeout; _bus.PolicyRegistry = policyRegistry; _bus.ProducerRegistry = producerRegistry; } } } }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IPolicyRegistry <string> policyRegistry, IAsyncCacheProvider memoryCache) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } Func <Context, HttpResponseMessage, Ttl> ttlFilter = (context, result) => new Ttl(result.IsSuccessStatusCode ? TimeSpan.FromSeconds(30) : TimeSpan.Zero); AsyncCachePolicy <HttpResponseMessage> policy = Policy.CacheAsync(memoryCache.AsyncFor <HttpResponseMessage>(), new ResultTtl <HttpResponseMessage>(ttlFilter)); policyRegistry.Add("cache", policy); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
public static IServiceCollection AddPolicies( this IServiceCollection services, IPolicyRegistry <string> policyRegistry, string keyPrefix, PolicyOptions policyOptions) { if (policyOptions != null) { policyRegistry?.Add( $"{keyPrefix}_{nameof(PolicyOptions.HttpRetry)}", HttpPolicyExtensions .HandleTransientHttpError() .WaitAndRetryAsync( policyOptions.HttpRetry.Count, retryAttempt => TimeSpan.FromSeconds(Math.Pow(policyOptions.HttpRetry.BackoffPower, retryAttempt)))); policyRegistry?.Add( $"{keyPrefix}_{nameof(PolicyOptions.HttpCircuitBreaker)}", HttpPolicyExtensions .HandleTransientHttpError() .CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: policyOptions.HttpCircuitBreaker.ExceptionsAllowedBeforeBreaking, durationOfBreak: policyOptions.HttpCircuitBreaker.DurationOfBreak)); return(services); } throw new InvalidOperationException($"{nameof(policyOptions)} is null"); }
/// <summary> /// Adds a set of rety and circuit breaker policies to the given policy registery with the given service name. /// </summary> /// <typeparam name="TService">The service for which the policies are being setup.</typeparam> /// <param name="services">The <see cref="IServiceCollection"/> to add the feature's services to.</param> /// <param name="config">The <see cref="IConfiguration"/> that defines Polly policy settings.</param> /// <param name="policyRegistry">The <see cref="IPolicyRegistry{TKey}"/> to add the new policies to.</param> /// <returns>A reference to this instance after the operation has completed.</returns> public static IServiceCollection AddPolicies <TService>( this IServiceCollection services, IConfiguration config, IPolicyRegistry <string> policyRegistry) { var policyOptions = new HttpPolicyOptions(); config.GetSection(nameof(HttpPolicyOptions)).Bind(policyOptions); policyRegistry?.Add( $"{typeof(TService).Name}_{PolicyType.Retry}", HttpPolicyExtensions .HandleTransientHttpError() .WaitAndRetryAsync( policyOptions.HttpRetryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(policyOptions.HttpRetryBackoffPower, retryAttempt)))); policyRegistry?.Add( $"{typeof(TService).Name}_{PolicyType.CircuitBreaker}", HttpPolicyExtensions .HandleTransientHttpError() .CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: policyOptions.CircuitBreakerToleranceCount, durationOfBreak: policyOptions.CircuitBreakerDurationOfBreak)); return(services); }
/// <summary> /// /// </summary> /// <param name="services"></param> /// <param name="configureClient"></param> /// <returns></returns> private static IHttpClientBuilder AddHttpClient(this IServiceCollection services, Action <HttpClient> configureClient) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (configureClient == null) { throw new ArgumentNullException(nameof(configureClient)); } IPolicyRegistry <string> registry = services.AddPolicyRegistry(); var timeout = Policy.TimeoutAsync <HttpResponseMessage>(TimeSpan.FromSeconds(10)); var longTimeout = Policy.TimeoutAsync <HttpResponseMessage>(TimeSpan.FromSeconds(60)); registry.Add("regular", timeout); registry.Add("long", longTimeout); return(services.AddHttpClient("SFExpress", configureClient) .AddPolicyHandler(Policy.TimeoutAsync <HttpResponseMessage>(TimeSpan.FromSeconds(100))) .AddPolicyHandlerFromRegistry("regular") .AddPolicyHandler((request) => { return request.Method == HttpMethod.Get ? timeout : longTimeout; }) .AddPolicyHandlerFromRegistry((reg, request) => { return request.Method == HttpMethod.Get ? reg.Get <IAsyncPolicy <HttpResponseMessage> >("regular") : reg.Get <IAsyncPolicy <HttpResponseMessage> >("long"); }) .AddTransientHttpErrorPolicy(p => p.RetryAsync()) .AddHttpMessageHandler(() => new RetryHandler()) .AddTypedClient <SfExpressService>()); }
public void ConfigureServices(IServiceCollection p_Services) { p_Services.AddMemoryCache(); p_Services.AddSingleton <IAsyncCacheProvider, MemoryCacheProvider>(); IPolicyRegistry <string> v_Registry = p_Services.AddPolicyRegistry(); p_Services.AddControllersWithViews(); p_Services.AddHttpClient("weather", context => { context.BaseAddress = new Uri("http://webapi"); }) .AddTypedClient(RestService.For <IWeatherService>) .AddPolicyHandlerFromRegistry(PolicySelector) .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(5) })) .AddTransientHttpErrorPolicy(builder => builder.CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: 3, durationOfBreak: TimeSpan.FromSeconds(30) )) ; }
public static void CreateCachingPolicy <T>(this IServiceProvider provider, string cacheKey, ITtlStrategy strategy) { IPolicyRegistry <string> registry = provider.GetRequiredService <IPolicyRegistry <string> >(); IAsyncPolicy <T> policy = Policy.CacheAsync <T>(provider.GetRequiredService <IAsyncCacheProvider>().AsyncFor <T>(), strategy); registry.Add(cacheKey, policy); }