Aplicações complexas e com múltiplas dependências são suscetíveis a falhas. Normalmente existe uma preocupação em evitar que essas falhas aconteçam, mas também é importante saber se recuperar quando elas acontecem (sim, elas vão acontecer). Polly é uma biblioteca para aplicações .NET que foca em resiliência e tratamento de falhas.
Polly implementa diferentes padrões, que são chamados de Policies. Na documentação são apresentados os diferentes tipos e um resumo do uso de cada um deles. O livro Release It apresenta muitos desses conceitos com mais detalhes.
Configurando o Polly
Configurar o Polly é bem simples, a biblioteca está disponível no NuGet e depois de instalada já está pronta para ser utilizada.
dotnet add package Polly --version 7.2.1
Retry Policy
Considerando os diferentes padrões disponíveis na biblioteca Polly, o Retry é o que eu mais utilizo. Esse padrão considera que a maioria das falhas que acontecem são transientes e que vão ser corrigidas automaticamente depois de um certo tempo. O Retry executa novamente um comportamento dada uma condição e é composto por algumas partes:
- Uma condição que irá determinar uma possível repetição
- Uma função que pode ser executada múltiplas vezes. Essa função pode ser síncrona ou assíncrona
- O número máximo de vezes que a operação irá ser repetida. No caso do RetryForever, esse parâmetro não é necessário e a execução vai se repetir até a condição ser falsa
- Um tempo de espera entre execuções (WaitAndRetry). Essa estratégia pode ajudar a aguardar o sistema se estabilizar
O Retry é muito útil para se recuperar de tratar falhas pontuais, como por exemplo:
- Uma dependência externa indisponível
- O banco não respondeu
- Um token expirado
Um cenário de uso do Retry
Considerando como exemplo uma aplicação que tem um carrinho de compras, um dos requisitos é calcular o frete. Essa aplicação tem uma dependência externa que traduz o CEP em um endereço. A dependência não é muito estável e em alguns momentos retorna erros. Nesse cenário, o Retry pode ser utilizado para lidar com esse caso de falha. Abaixo temos um exemplo dessa implementação.
public class DeliverCalculator | |
{ | |
private readonly ILogger logger; | |
private readonly HttpClient client; | |
public DeliverCalculator(ILogger logger, HttpClient client) | |
{ | |
this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); | |
this.client = new HttpClient(); | |
} | |
public async Task<HttpResponseMessage> RetrieveCEP() | |
{ | |
var retryCount = 2; | |
var policy = HttpPolicyExtensions.HandleTransientHttpError() | |
.WaitAndRetryAsync( | |
retryCount: retryCount, | |
sleepDurationProvider: (retryAttempt) => TimeSpan.FromSeconds(retryAttempt), | |
onRetry: (result, duration, retryAttempt, context) | |
=> logger.LogWarning($"Retry attempty number {retryAttempt}. Waiting for {duration} seconds.") | |
); | |
var result = await policy.ExecuteAsync(() => client.GetAsync("cep")); | |
return result; | |
} | |
} |
No código estamos usando um método chamado ‘HandleTransientHttpError’, disponível em uma biblioteca de extensões do Polly, esse método agrupa algumas condições de falha comuns com o uso do HttpClient. Internamente, essa condição valida se o retorno de uma requisição é um erro com um status code maior que 500 (indica um erro), 408 (timeout) ou uma exceção do tipo HttpRequestException.
Essa policy criada executa a chamada para a dependência externa até duas vezes (retryCount) se o resultado da chamada se encaixar na condição descrita acima. Como esse Retry é do tipo WaitAndRetry, então antes de executar novamente, a Policy vai aguardar um tempo determinado.
O parâmetro de duração é configurado através de uma função, no exemplo acima, a Policy vai aguardar a quantidade de segundos relativa ao número daquela execução: na primeira tentativa um segundo, na segunda tentativa dois segundos.
Esse é um exemplo onde Polly pode ser utilizado para lidar com falhas em aplicações .NET. O código é simples e reutilizável e evita a implementação de uma camada de complexidade extra para lidar com falhas.
Referências
- Neste repositório existem vários exemplos práticos do uso do Polly
- Wiki do Retry com mais detalhes
Top comments (2)
Parabéns pelo post, rápido e objetivo.
Que legal Cynthia não conhecia essa ferramenta, obrigada por compartilhar :)