public static IServiceCollection ConfigurarRefit(this IServiceCollection services, PoliciesOptions policies, string urlBase) { //Definindo policies de Retry e timeout AsyncRetryPolicy <HttpResponseMessage> retryPolicy = HttpPolicyExtensions .HandleTransientHttpError() .WaitAndRetryAsync(policies.WaitAndRetryConfig.Retry, _ => TimeSpan.FromMilliseconds(policies.WaitAndRetryConfig.Wait)); AsyncTimeoutPolicy <HttpResponseMessage> timeoutPolicy = Policy .TimeoutAsync <HttpResponseMessage>(TimeSpan.FromMilliseconds(policies.WaitAndRetryConfig.Timeout)); //Adicionar o client do Refit nas interfaces de serviços services.AddRefitClient <IRendaFixaService>() .ConfigureHttpClient(c => c.BaseAddress = new Uri(urlBase)) .AddPolicyHandler(retryPolicy) .AddPolicyHandler(timeoutPolicy); services.Decorate <IRendaFixaService, RendaFixaService>(); services.AddRefitClient <IFundosService>() .ConfigureHttpClient(c => c.BaseAddress = new Uri(urlBase)) .AddPolicyHandler(retryPolicy) .AddPolicyHandler(timeoutPolicy); services.Decorate <IFundosService, FundosService>(); services.AddRefitClient <ITesouroDiretoService>() .ConfigureHttpClient(c => c.BaseAddress = new Uri(urlBase)) .AddPolicyHandler(retryPolicy) .AddPolicyHandler(timeoutPolicy); services.Decorate <ITesouroDiretoService, TesouroDiretoService>(); return(services); }
public WaitRetryDelegateTimeoutService() { httpClient.BaseAddress = new Uri("https://localhost:44354/"); httpClient.Timeout = new TimeSpan(0, 0, 30); httpClient.DefaultRequestHeaders.Clear(); httpWaitAndRetry = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) / 2)); // this is not the same as setting timeout for HttpClient // if the request does not respond in the given time (ex. 5 seconds), TimeoutRejectedException is thrown timeoutPolicy = Policy.TimeoutAsync <HttpResponseMessage>(5, TimeoutStrategy.Pessimistic); httpretryPolicyForHttpClienTimeout = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .Or <HttpRequestException>() .RetryAsync(1, onRetry: OnRetry); httpWaitAndRetryWithDelegate = 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; }); httpFallbackPolicy = Policy.HandleResult <HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.NotFound) .FallbackAsync(new HttpResponseMessage(HttpStatusCode.OK) { }); }
public Task <HttpResponseMessage> MakeRetryingCall( Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > asyncHttpCall, HttpRequestMessage requestMessage, CancellationToken cancellationToken) { AsyncTimeoutPolicy timeOutPolicy = Policy.TimeoutAsync( retryConfiguration.TotalElapsedTimeInSecs, TimeoutStrategy.Optimistic, onTimeoutAsync: (context, timespan, t1, exception) => throw new OciException( HttpStatusCode.RequestTimeout, "Request has been timed out. Please increase the total elapsed time for this request and retry", "Unknown", exception) ); AsyncRetryPolicy <HttpResponseMessage> retryAndSleepPolicy = Policy .HandleResult <HttpResponseMessage>(r => ShoulRetryOnHttpResponse(r)) .WaitAndRetryAsync( retryCount: retryConfiguration.MaxAttempts, sleepDurationProvider: (retryCount, response, context) => TimeSpan.FromSeconds(retryConfiguration.GetNextDelayInSeconds(retryCount)), onRetryAsync: async(response, timespan, retryAttempt, context) => { logger.Info($"Retry Attempt: {retryAttempt}"); await Task.CompletedTask; } ); return(timeOutPolicy .WrapAsync(retryAndSleepPolicy) .ExecuteAsync(() => asyncHttpCall.Invoke(requestMessage, cancellationToken))); }
public static AsyncPolicyWrap CreateExecutionPolicyWrapper() { // Following example causes the policy to return a bad request HttpResponseMessage with a probability of 5% if enabled var fault = new CosmosException("Simulated cosmos exception", HttpStatusCode.ServiceUnavailable, -1, "", 0); AsyncInjectOutcomePolicy injectOutcomePolicy = CreateChaosFaultPolicy <CosmosException>(fault); AsyncTimeoutPolicy timeoutPolicy = CreateTimeOutPolicy(5, TimeoutStrategy.Pessimistic); return(Policy.WrapAsync(timeoutPolicy, injectOutcomePolicy)); }
public static void Build(IPolicyRegistry <string> registry) { //PolicyRegistry registry = new PolicyRegistry(); //Basic Retry Policy AsyncRetryPolicy <HttpResponseMessage> basicRetryPolicy = Policy.HandleResult <HttpResponseMessage>(result => !result.IsSuccessStatusCode) .RetryAsync(2); registry.Add(BasicRetryPolicy, basicRetryPolicy); //Wait and Retry Policy AsyncRetryPolicy <HttpResponseMessage> waitAndRetryPolicy = Policy.HandleResult <HttpResponseMessage>(result => !result.IsSuccessStatusCode) .WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromMilliseconds(100 * retryAttempt), onRetryAsync: WaitAndRetryHandler); registry.Add(WaitAndRetryPolicy, waitAndRetryPolicy); ////Retry Policy with onRetryAsync Delegate AsyncRetryPolicy <HttpResponseMessage> retryWithDelegatePolicy = Policy.HandleResult <HttpResponseMessage>(result => !result.IsSuccessStatusCode) .RetryAsync(2, onRetryAsync: OnRetry); registry.Add(RetryWithDelegatePolicy, retryWithDelegatePolicy); ////Retry Policy or HttpRequestException along with onRetryAsync Delegate AsyncRetryPolicy <HttpResponseMessage> retryOrExceptionPolicy = Policy.HandleResult <HttpResponseMessage>(result => !result.IsSuccessStatusCode) .Or <HttpRequestException>() .RetryAsync(2, onRetryAsync: OnRetry); registry.Add(RetryOrExceptionPolicy, retryOrExceptionPolicy); //Fallback Policy AsyncFallbackPolicy <HttpResponseMessage> asyncFallbackPolicy = Policy.HandleResult <HttpResponseMessage>(result => !result.IsSuccessStatusCode) .Or <TimeoutRejectedException>() .FallbackAsync(new HttpResponseMessage(HttpStatusCode.OK) { Content = new ObjectContent(typeof(int), int.MaxValue, new JsonMediaTypeFormatter()) }, onFallbackAsync: FallbackAsyncHandler); registry.Add(FallbackWithTimedOutExceptionPolicy, asyncFallbackPolicy); //TimeoutPolicy AsyncTimeoutPolicy <HttpResponseMessage> timeoutPolicy = Policy.TimeoutAsync <HttpResponseMessage>(1, onTimeoutAsync: TimeoutAsyncHandler); registry.Add(TimeoutPolicy, timeoutPolicy); }
async Task TimeoutPolicy() { AsyncTimeoutPolicy timeoutPolicy = Policy.TimeoutAsync(5, TimeoutStrategy.Pessimistic, onTimeoutAsync: (context, timespan, task) => { _logger.LogError($"{context.PolicyKey} at {context.OperationKey}: execution timed out after {timespan.TotalSeconds} seconds."); _cts.Cancel(); _cts = new CancellationTokenSource(); ExecuteAsync(_cts.Token).GetAwaiter(); return(Task.CompletedTask); }); HttpResponseMessage httpResponse = await timeoutPolicy .ExecuteAsync(async ct => await _apiClient.SendRequest(_cts.Token), _cts.Token); }
public async Task <PolicyResult <TOutput> > ExecuteWithTimeoutAsync <TOutput>(Func <CancellationToken, TOutput> func, int timeout, CancellationToken relatedToken) { CancellationEnforcer <TOutput> cancellationEnforcer = new CancellationEnforcer <TOutput>(); // need a little bit of extra time to allow the globalTimer to execute first AsyncTimeoutPolicy timeoutPolicy = Policy.TimeoutAsync(timeout + 1, TimeoutStrategy.Optimistic); PolicyResult <TOutput> policyResult = await timeoutPolicy.ExecuteAndCaptureAsync( async ct => await cancellationEnforcer.AskVinnyToKeepWatch(func, ct), relatedToken ); return(policyResult); }
public static async Task Run() { AsyncTimeoutPolicy policy = GetPolicy(); var cancellationToken = new CancellationToken(); await policy.ExecuteAsync(async (ct) => { Console.WriteLine($"Start Execution at {DateTime.UtcNow.ToLongTimeString()}"); await Task.Delay(10000, ct); Console.WriteLine($"Finish Execution at {DateTime.UtcNow.ToLongTimeString()}"); }, cancellationToken); Console.WriteLine("Done"); }
//constructor injection public Cats(HttpClient httpClient, IOptions <ConfigSettings> config) { _httpClient = httpClient; _urls = config.Value; //handle re-tries for http failures (can be pushed to start up at time of registeration) _httpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(msg => msg.StatusCode == System.Net.HttpStatusCode.GatewayTimeout) .Or <TimeoutRejectedException>() .WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); //set timeout policy _timeoutPolicy = Policy.TimeoutAsync(25); }
private static IAsyncPolicy <HttpResponseMessage> GetRetryPolicy() { AsyncTimeoutPolicy timeout = Policy.TimeoutAsync(7); return(HttpPolicyExtensions // Handle HttpRequestExceptions, 408 and 5xx status codes .HandleTransientHttpError() // Handle 404 not found .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) // Handle 401 Unauthorized .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.Unauthorized) // What to do if any of the above erros occur: // Retry 3 times, each time wait 1,2 and 4 seconds before retrying. .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))).WrapAsync(timeout)); }
public AglIdentitySvc(HttpClient httpClient, ILogger <AglIdentitySvc> logger, IOptions <IdentityConfig> config) { client = httpClient; _logger = logger; _urls = config.Value; //set polly retry policies for microservices _httpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(msg => msg.StatusCode == System.Net.HttpStatusCode.GatewayTimeout) .Or <TimeoutRejectedException>() .WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); //set timeout policy _timeoutPolicy = Policy.TimeoutAsync(25); }
public static IServiceCollection AddHelloClient(this IServiceCollection services) { // --> Create: Polly policy. AsyncRetryPolicy <HttpResponseMessage> retryPolicy = HttpPolicyExtensions .HandleTransientHttpError() .Or <TimeoutRejectedException>() // Thrown by Polly's TimeoutPolicy if the inner call gets timeout. .WaitAndRetryAsync(2, _ => TimeSpan.FromMilliseconds(500)); AsyncTimeoutPolicy <HttpResponseMessage> timeoutPolicy = Policy .TimeoutAsync <HttpResponseMessage>(TimeSpan.FromMilliseconds(500)); services.AddHttpClient <IHelloClient, HelloClient>(c => c.BaseAddress = new Uri("http://localhost:5000")) .AddPolicyHandler(retryPolicy) .AddPolicyHandler(timeoutPolicy); return(services); }
public CatalogController() { _timeoutPolicy = Policy.TimeoutAsync <HttpResponseMessage>(1, onTimeoutAsync: TimeoutDelegate); _httpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .Or <TimeoutRejectedException>() .RetryAsync(3, onRetry: HttpRetryPolicyDelegate); _httpRequestFallbackPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .Or <TimeoutRejectedException>() .FallbackAsync(new HttpResponseMessage(HttpStatusCode.OK) { Content = new ObjectContent(_cachedResult.GetType(), _cachedResult, new JsonMediaTypeFormatter()) }, onFallbackAsync: HttpRequestFallbackPolicyDelegate); _policyWrap = Policy.WrapAsync(_httpRequestFallbackPolicy, _httpRetryPolicy, _timeoutPolicy); }
public CatalogController() { // throws TimeoutRejectedException if timeout of 1 second is exceeded. _httpTimeoutPolicy = Policy.TimeoutAsync(1); _httpRetryPolicy = Policy .HandleResult <HttpResponseMessage>(response => !response.IsSuccessStatusCode) .Or <TimeoutRejectedException>() .RetryAsync(3); _httpFallbackPolicy = Policy .HandleResult <HttpResponseMessage>(response => !response.IsSuccessStatusCode) .Or <TimeoutRejectedException>() .FallbackAsync( new HttpResponseMessage(HttpStatusCode.OK) { Content = new ObjectContent(_cachedResult.GetType(), _cachedResult, new JsonMediaTypeFormatter()) } ); }
internal static ICameraBotBuilder AddHttpClient(this ICameraBotBuilder builder) { using ServiceProvider serviceProvider = builder.Services.BuildServiceProvider(false); CameraBotOptions options = serviceProvider.GetRequiredService <IOptions <CameraBotOptions> >().Value; AsyncRetryPolicy <HttpResponseMessage> retryPolicy = HttpPolicyExtensions .HandleTransientHttpError() .Or <TimeoutRejectedException>() .RetryAsync(options.RetryCount); AsyncTimeoutPolicy <HttpResponseMessage> timeoutPolicy = Policy.TimeoutAsync <HttpResponseMessage>(TimeSpan.FromMilliseconds(options.TimeoutMilliseconds)); builder.Services .AddHttpClient <ICameraService, CameraService>() .AddPolicyHandler(retryPolicy) .AddPolicyHandler(timeoutPolicy); return(builder); }
public CatalogController() { //simple retry // _httpRetryPolicy = Policy // .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode) // .RetryAsync(3); //simple retry includes timeout _httpRetryPolicy = Policy .HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .Or <HttpRequestException>() .Or <TimeoutRejectedException>() .RetryAsync(3, onRetry); //simpley retry com funcao quando fail pre retry // _httpRetryPolicy = Policy // .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode) // .RetryAsync(3, (res, retryCounter) => // { // if(res.Result.StatusCode == System.Net.HttpStatusCode.Unauthorized) { // _httpClient = GetHttpClientWithCookie(); // } // }); //backoff retry //aumenta o delay para o retry por potencia // _httpRetryPolicy = Policy // .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode) // .WaitAndRetryAsync(3, retryTime => TimeSpan.FromSeconds(Math.Pow(2, retryTime) / 2)); //fallback (cached values on req fails) _fallbackPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode) .Or <TimeoutRejectedException>() .FallbackAsync(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("99") }); _timeoutPolicy = Policy.TimeoutAsync(2); }
public PollyQoSProvider(DownstreamReRoute reRoute, IOcelotLoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger <PollyQoSProvider>(); Enum.TryParse(reRoute.QosOptions.TimeoutStrategy, out TimeoutStrategy strategy); _timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(reRoute.QosOptions.TimeoutValue), strategy); if (reRoute.QosOptions.ExceptionsAllowedBeforeBreaking > 0) { _circuitBreakerPolicy = Policy .Handle <HttpRequestException>() .Or <TimeoutRejectedException>() .Or <TimeoutException>() .CircuitBreakerAsync( exceptionsAllowedBeforeBreaking: reRoute.QosOptions.ExceptionsAllowedBeforeBreaking, durationOfBreak: TimeSpan.FromMilliseconds(reRoute.QosOptions.DurationOfBreak), onBreak: (ex, breakDelay) => { _logger.LogError( ".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex); }, onReset: () => { _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."); }, onHalfOpen: () => { _logger.LogDebug(".Breaker logging: Half-open; next call is a trial."); } ); } else { _circuitBreakerPolicy = null; } CircuitBreaker = new CircuitBreaker(_circuitBreakerPolicy, _timeoutPolicy); }
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); WaitAndRetryConfig wrc = Configuration.BindTo <WaitAndRetryConfig>(); // Add: MessageHandler(s) to the DI container. services.AddTransient <AuthorizationMessageHandler>(); // --> Create: Polly policy. AsyncRetryPolicy <HttpResponseMessage> retryPolicy = HttpPolicyExtensions .HandleTransientHttpError() .Or <TimeoutRejectedException>() // Thrown by Polly's TimeoutPolicy if the inner call gets timeout. .WaitAndRetryAsync(wrc.Retry, _ => TimeSpan.FromMilliseconds(wrc.Wait)); AsyncTimeoutPolicy <HttpResponseMessage> timeoutPolicy = Policy .TimeoutAsync <HttpResponseMessage>(TimeSpan.FromMilliseconds(wrc.Timeout)); // !! Problem: AuthorizationHeaderValueGetter is not called by the library, if you add with AddRefitClient. //RefitSettings refitSettings = new RefitSettings //{ // AuthorizationHeaderValueGetter = () => Task.FromResult("TestToken") //}; // --> Add: RefitClient. services.AddRefitClient <IUserClient>() .ConfigureHttpClient(c => c.BaseAddress = new Uri("http://localhost:5000")) .AddPolicyHandler(retryPolicy) .AddPolicyHandler(timeoutPolicy) // The order of adding is imporant! .AddHttpMessageHandler <AuthorizationMessageHandler>(); // RefitSettings does not work. // --> Decorate IUserClient(RefitClient) with UserClient implementation. services.Decorate <IUserClient, UserClient>(); services.AddRefitClient <IJsonPlaceholderClient>() .ConfigureHttpClient(c => c.BaseAddress = new Uri("http://jsonplaceholder.typicode.com")); }
public Task <HttpResponseMessage> MakeRetryingCall( Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > asyncHttpCall, HttpRequestMessage requestMessage, CancellationToken cancellationToken) { AsyncTimeoutPolicy timeOutPolicy = Policy.TimeoutAsync( retryConfiguration.TotalElapsedTimeInSecs, TimeoutStrategy.Optimistic, onTimeoutAsync: (context, timespan, t1, exception) => throw new OciException( HttpStatusCode.RequestTimeout, "Request has been timed out. Please increase the total elapsed time for this request and retry", "Unknown", exception) ); AsyncRetryPolicy <HttpResponseMessage> retryAndSleepPolicy = Policy .HandleResult <HttpResponseMessage>(r => ShoulRetryOnHttpResponse(r)) .WaitAndRetryAsync( retryCount: retryConfiguration.MaxAttempts, sleepDurationProvider: (retryCount, response, context) => TimeSpan.FromSeconds(retryConfiguration.GetNextDelayInSeconds(retryCount)), onRetryAsync: async(response, timespan, retryAttempt, context) => { logger.Info($"Retry Attempt: {retryAttempt}"); await Task.CompletedTask.ConfigureAwait(false); } ); return(timeOutPolicy .WrapAsync(retryAndSleepPolicy) .ExecuteAsync(async() => { // A new copy of the request message needs to be created because it is disposed each time it is sent, and // resending the same request will result in the following error message: // "The request message was already sent. Cannot send the same request message multiple times." var newRequestMessage = CloneHttpRequestMessage(requestMessage); return await asyncHttpCall.Invoke(newRequestMessage, cancellationToken).ConfigureAwait(false); })); }
public CatalogController(IHttpClientFactory clientFactory) { _httpClientFactory = clientFactory; _httpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(result => result.StatusCode == System.Net.HttpStatusCode.InternalServerError) .Or <TimeoutRejectedException>() .RetryAsync(3); _httpWaitAndRetryPolicy = Policy.HandleResult <HttpResponseMessage>(result => !result.IsSuccessStatusCode) .WaitAndRetryAsync(3, sleepDurationProvider: retryCount => TimeSpan.FromSeconds(Math.Pow(2, retryCount) / 2), onRetry: (httpResponseMessage, time, context) => { if (httpResponseMessage.Result.StatusCode == System.Net.HttpStatusCode.Unauthorized) { Debug.WriteLine("There was issue with authentication"); } else { if (context.Contains("Logging") && context["Logging"].ToString() == "Enabled") { Debug.WriteLine(httpResponseMessage.Result.Content.ReadAsStringAsync().Result); } } }); _fallbackPolicy = Policy.HandleResult <HttpResponseMessage>(result => !result.IsSuccessStatusCode) .FallbackAsync(new HttpResponseMessage(System.Net.HttpStatusCode.OK) { Content = new StringContent("Cached Default Result") }); _timeoutPolicy = Policy.TimeoutAsync(seconds: 1); _policyWrap = _fallbackPolicy.WrapAsync(_httpWaitAndRetryPolicy.WrapAsync(_timeoutPolicy)); }
/// <summary> /// Generates the circuit breaker policy for a service. /// </summary> /// <param name="serviceInfo">The service to generate the circuit breaker policy for</param> /// <returns>The circuit policy</returns> protected AsyncPolicyWrap <ServiceResponse> GetCircuitBreakerPolicy(CalledServiceInfo serviceInfo) { return(CircuitBreakerPolicies.GetOrAdd(serviceInfo.CacheKey, _ => { AsyncTimeoutPolicy timeoutPolicy = Policy .TimeoutAsync( serviceInfo.Timeout, TimeoutStrategy.Pessimistic ); AsyncCircuitBreakerPolicy <ServiceResponse> circuitBreakerPolicy = Policy <ServiceResponse> .Handle <TimeoutRejectedException>() .OrResult(resultPredicate: serviceResponse => serviceResponse.Status == ServiceResponseStatus.Error) .CircuitBreakerAsync( handledEventsAllowedBeforeBreaking: serviceInfo.CircuitBreakerInfo.ExceptionCount, durationOfBreak: serviceInfo.CircuitBreakerInfo.BreakDuration, onBreak: (__, ___) => { Log.Warning("Service ({ServiceName}) has reached its threshold for the circuit breaker and the circuit has been opened", serviceInfo.Name); }, onReset: () => { Log.Warning("Service ({ServiceName}) has been determined to be back up, circuit closed again", serviceInfo.Name); } ); AsyncPolicyWrap <ServiceResponse> circuitBreakerWrappingTimeout = circuitBreakerPolicy .WrapAsync(timeoutPolicy); AsyncFallbackPolicy <ServiceResponse> timeoutFallbackPolicy = Policy <ServiceResponse> .Handle <TimeoutRejectedException>() .FallbackAsync( cancellationToken => { return Task.FromResult(new ServiceResponse { Status = ServiceResponseStatus.Timeout, ServiceId = serviceInfo.Id }); }); AsyncPolicyWrap <ServiceResponse> timeoutFallbackPolicyWrappingCircuitBreaker = timeoutFallbackPolicy .WrapAsync(circuitBreakerWrappingTimeout); AsyncFallbackPolicy <ServiceResponse> exceptionFallbackPolicy = Policy <ServiceResponse> .Handle <Exception>() .FallbackAsync( cancellationToken => { return Task.FromResult(new ServiceResponse { Status = ServiceResponseStatus.Error, ServiceId = serviceInfo.Id }); }); AsyncPolicyWrap <ServiceResponse> exceptionFallbackPolicyWrappingTimeoutFallback = exceptionFallbackPolicy .WrapAsync(timeoutFallbackPolicyWrappingCircuitBreaker); AsyncPolicyWrap <ServiceResponse> policy = exceptionFallbackPolicyWrappingTimeoutFallback; return policy; })); }
public async Task <IEnumerable <Result> > GetHeroes(string limite) { //if(_client == null) //{ //_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //_client.BaseAddress //} //Posso melhorar o tratamento do handleResult //https://dev.to/rickystam/net-core-use-httpclientfactory-and-polly-to-build-rock-solid-services-2edh //referencia //https://www.davidbritch.com/2017/07/transient-fault-handling-in.html _httpRetryPolicy = Policy.HandleResult <HttpResponseMessage>(r => httpStatusCodesToRetry.Contains(r.StatusCode)) .Or <TimeoutRejectedException>() .Or <Exception>() //.OrResult<HttpResponseMessage>(r => httpStatusCodesToRetry.Contains(r.StatusCode)) //.Handle<HttpRequestException>(ex => !ex.Message.ToLower().Contains("404")) .WaitAndRetryAsync ( //Quantidade de tentaivas retryCount: 3, //duração entre as tentativas sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), //O que será executado se der erro onRetry: async(response, time, retryCount, context) => { if (response.Exception != null) { Console.WriteLine($"Ocorreu um erro ao baixar os dados: {response.Exception.Message}, Tentando novamente em {time}, tentativa número: {retryCount}"); } else { var rawResponse = await response.Result.Content.ReadAsStringAsync(); var json = JsonConvert.DeserializeAnonymousType(rawResponse, new { code = "", status = "" }); Console.WriteLine($"Ocorreu um erro ao baixar os dados: {json.status}, Tentando novamente em {time}, tentativa número: {retryCount}"); } } ); _timeoutPolicy = Policy.TimeoutAsync(5, TimeoutStrategy.Pessimistic); try { //.ExecuteAsync(async () => //{ // Console.WriteLine($"Obtendo Herois..."); // var response = await client.GetAsync(GetUrl(limite)); // var rawResponse = await response.Content.ReadAsStringAsync(); //Problemas para retornar um await direito, a melhor opção por enquantp é deixar finalizar o metodo e retornar o objeto depois //heroes = JsonConvert.DeserializeObject<Hero>(rawResponse); //}); //Referencia //https://nodogmablog.bryanhogan.net/2017/12/using-the-polly-timeout-when-making-a-http-request/ HttpResponseMessage response = await _httpRetryPolicy.ExecuteAsync(() => _timeoutPolicy.ExecuteAsync(async c => await _client.GetAsync(GetUrl(limite), c), CancellationToken.None)); if (response.StatusCode != HttpStatusCode.OK) { var newtonSoft = string.IsNullOrEmpty(await response.Content.ReadAsStringAsync()) ? JsonConvert.DeserializeObject <Hero>(await response.Content.ReadAsStringAsync()) : new Hero(); return(new List <Result>().DefaultIfEmpty()); } else { //Teste Jil //Stopwatch TimerJill = new Stopwatch(); //TimerJill.Start(); //var employeeDeserialized = JSON.Deserialize<Hero>(await response.Content.ReadAsStringAsync(), new Options(dateFormat: DateTimeFormat.MicrosoftStyleMillisecondsSinceUnixEpoch)); //TimerJill.Stop(); //var tempoDecorridoJil = TimerJill.Elapsed.TotalSeconds; var contractResolver = new CustomContractResolver(); //Teste using newtonsof Stopwatch TimerNewton = new Stopwatch(); TimerNewton.Start(); //forma correta de utilizar, sem jogar atribuir para uma string antes de realizar a deserialização. var newtonSoft = JsonConvert.DeserializeObject <Hero>(await response.Content.ReadAsStringAsync(), new JsonSerializerSettings { ContractResolver = contractResolver }); TimerNewton.Stop(); var tempoDecorridoNewton = TimerNewton.Elapsed.TotalSeconds; Stopwatch TimerUsing = new Stopwatch(); TimerUsing.Start(); Hero hero; //Referencia: http://jonathanpeppers.com/Blog/improving-http-performance-in-xamarin-applications using (var stream = await response.Content.ReadAsStreamAsync()) //Referencia minBuffer https://stackoverflow.com/questions/56461022/benchmarking-newtonsoft-json-deserialization-from-stream-and-from-string using (var reader = new StreamReader(stream, Encoding.UTF8, true, 128)) using (var jsonTextReader = new JsonTextReader(reader)) { hero = _serializer.Deserialize <Hero>(jsonTextReader); } TimerUsing.Stop(); var tempoDecorridoUsing = TimerUsing.Elapsed.TotalSeconds; string json = await response.Content.ReadAsStringAsync(); //Referencia //https://stackoverflow.com/questions/8707755/how-to-know-the-size-of-the-string-in-bytes var howManyBytes = json.Length * sizeof(Char); return(newtonSoft.data.results.EmptyIfNull()); } /* * * * * * await Policy * //Se for um erro diferente de 404 ira executar a politica de retry * //podemos utilizar grupo de statusCode * //o ideal é trabalhar em cima dos erros de internet, e continuar tratando o resto pelo statusCode * * //.Handle<TimeoutException>() * .Handle<HttpRequestException>(ex => !ex.Message.ToLower().Contains("404")) * .Or<HttpRequestException>() * //.OrResult<HttpResponseMessage>(r => httpStatusCodesToRetry.Contains(r.StatusCode)) * //.Handle<HttpRequestException>(ex => !ex.Message.ToLower().Contains("404")) * * .WaitAndRetryAsync * ( * //Quantidade de tentaivas * retryCount: 3, * * //duração entre as tentativas * sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), * * //O que será executado se der erro * onRetry: (ex, time) => * { * lock (_MessageLock) * { * Console.BackgroundColor = ConsoleColor.Red; * Console.WriteLine($"Ocorreu um erro ao baixar os dados: {ex.Message}, tentando novamente em...{time}"); * Console.ResetColor(); * } * } * ) * .ExecuteAsync(async () => * { * var response = await client.GetAsync(GetUrl(limite)); * var rawResponse = await response.Content.ReadAsStringAsync(); * * //Problemas para retornar um await direito, a melhor opção por enquantp é deixar finalizar o metodo e retornar o objeto depois * heroes = JsonConvert.DeserializeObject<Hero>(rawResponse); * }); * */ /* * var response = await client.GetAsync(GetUrl(limite)); * * if (response.StatusCode != System.Net.HttpStatusCode.OK) * { * throw new Exception(response.Content.ReadAsStringAsync().Result); * } * var rawResponse = await response.Content.ReadAsStringAsync(); * return JsonConvert.DeserializeObject<Hero>(rawResponse); * */ //return heroes; } catch (Exception ex) { throw ex; } }