Retry Pattern

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: