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:

 1public class Retrier<TResult> 
 2{
 3    public TResult Try(Func<TResult> func, 
 4        int maxRetries)
 5    {
 6        TResult returnValue = default(TResult);
 7        int numTries = 0;
 8        bool succeeded = false;
 9        while (numTries < maxRetries)
10        {
11            try
12            {
13                returnValue = func();
14                succeeded = true;
15            }
16            catch (Exception)
17            {
18                //todo: figure out what to do here
19            }
20            finally
21            {
22                numTries++;
23            }
24            if (succeeded)
25                return returnValue;
26        }
27        return default(TResult);
28    }
29 
30    public TResult TryWithDelay(Func<TResult> func, int maxRetries, 
31        int delayInMilliseconds)
32    {
33        TResult returnValue = default(TResult);
34        int numTries = 0;
35        bool succeeded = false;
36        while (numTries < maxRetries)
37        {
38            try
39            {
40                returnValue = func();
41                succeeded = true;
42            }
43            catch (Exception)
44            {
45                //todo: figure out what to do here
46            }
47            finally
48            {
49                numTries++;
50            }
51            if (succeeded)
52                return returnValue;
53            System.Threading.Thread.Sleep(delayInMilliseconds);
54        }
55        return default(TResult);
56    }
57}

Referências: