Example #1
0
        public async Task <IActionResult> Get(int id)
        {
            var httpClient = GetHttpClient();

            string requestEndpoint = $"samples/timeout-policy/inventory/{id}";

            var response = await _httpFallbackPolicy
                           .ExecuteAsync(() => _httpRetryPolicy
                                         .ExecuteAsync(() => _httpTimeoutPolicy
                                                       .ExecuteAsync(token => httpClient.GetAsync(requestEndpoint, token), CancellationToken.None)));

            if (response.IsSuccessStatusCode)
            {
                var itemsInStock = JsonConvert.DeserializeObject <int>(await response.Content.ReadAsStringAsync());

                return(Ok(itemsInStock));
            }

            if (response.Content != null)
            {
                return(StatusCode((int)response.StatusCode, response.Content.ReadAsStringAsync()));
            }

            return(StatusCode((int)response.StatusCode));
        }
Example #2
0
    public async Task <IActionResult> Get(int id)
    {
        _httpClient = GetHttpClient();

        string url = $"inventory/{id}";

        // HttpResponseMessage res = await _httpRetryPolicy.ExecuteAsync(() => _httpClient.GetAsync(url));

        //Chaining Policies Fallback With Retry
        // HttpResponseMessage res = await _fallbackPolicy
        // .ExecuteAsync(
        //     () => _httpRetryPolicy.ExecuteAsync(() => _httpClient.GetAsync(url))
        // );

        //Chaining Policies Fallback With Retry and Timeout
        HttpResponseMessage res = await _fallbackPolicy
                                  .ExecuteAsync(() => _httpRetryPolicy
                                                .ExecuteAsync(() => _timeoutPolicy
                                                              .ExecuteAsync(() => _httpClient.GetAsync(url))));

        if (res.IsSuccessStatusCode)
        {
            var body = JsonConvert.DeserializeObject <int>(await res.Content.ReadAsStringAsync());
            return(Ok(body));
        }

        return(StatusCode((int)res.StatusCode, res.Content.ReadAsStringAsync()));
    }
Example #3
0
 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);
 }
Example #4
0
        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");
        }
        public async Task TimeoutPolicy()
        {
            // api/contactsss is an invalid endpoint
            var response = await timeoutPolicy.ExecuteAsync(() => GetData());

            response.EnsureSuccessStatusCode();
            var content = await response.Content.ReadAsStringAsync();

            var contacts = new List <ContactViewModel>();

            if (response.Content.Headers.ContentType.MediaType == "application/json")
            {
                contacts = JsonConvert.DeserializeObject <List <ContactViewModel> >(content);
            }
            else if (response.Content.Headers.ContentType.MediaType == "application/xml")
            {
                var serializer = new XmlSerializer(typeof(List <ContactViewModel>));
                contacts = (List <ContactViewModel>)serializer.Deserialize(new StringReader(content));
            }

            foreach (var contact in contacts)
            {
                Console.WriteLine($"Name: {contact.Name}, Address: {contact.Address}");
            }
        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;
            }
        }