Retry Pattern
Overview
Olha só, tropa de programadores! Hoje, vamos desbravar o universo do padrão de desenvolvimento Retry, o herói que tenta, tenta de novo, e não desiste até sua aplicação web falar de boa com o banco de dados. Mas ó, nem tudo são flores, e vou te contar quando esse padrão pode te deixar na mão. Prepara o café e se aconchega, porque o papo hoje é técnico, mas prometo te guiar com leveza por essa aventura de código!
Este padrão de desenvolvimento foi criado para tratar erros e exceções que são previstos e podem ocorrer, independentemente das precauções que o programador pode tomar.
Uma aplicação web que depende de um banco de dados pode implementar este padrão para, caso ocorra algum erro de comunicação com o banco de dados, tente novamente X vezes.
Situações que este padrão pode não se aplicar:
- Quando o erro não é algo rápido, pois isso afetar diretamente a capacidade de resposta da aplicação. Pode ser que, ao aplicar este padrão, você esteja desperdiçando tempo e recursos em requisições que, provavelmente, vão falhar;
- Tratar erros e exceções causados por erros em lógica de negócio;
- Como uma alternativa para abordar problemas de escalabilidade em um sistema;
O exemplo abaixo não é dos mais simples, mas demonstra bem o padrão Retry:
public class Retrier<TResult>
{
public TResult Try(Func<TResult> func,
int maxRetries)
{
TResult returnValue = default(TResult);
int numTries = 0;
bool succeeded = false;
while (numTries < maxRetries)
{
try
{
returnValue = func();
succeeded = true;
}
catch (Exception)
{
//todo: figure out what to do here
}
finally
{
numTries++;
}
if (succeeded)
return returnValue;
}
return default(TResult);
}
public TResult TryWithDelay(Func<TResult> func, int maxRetries,
int delayInMilliseconds)
{
TResult returnValue = default(TResult);
int numTries = 0;
bool succeeded = false;
while (numTries < maxRetries)
{
try
{
returnValue = func();
succeeded = true;
}
catch (Exception)
{
//todo: figure out what to do here
}
finally
{
numTries++;
}
if (succeeded)
return returnValue;
System.Threading.Thread.Sleep(delayInMilliseconds);
}
return default(TResult);
}
}
Referências: