Poor Man Retry Pattern

We all encounter infrastructure, databases, APIs availability issues at various times. Most of the time, processes are not designed to automatically resume on errors, or at least, to retry (as far as possible) or to wait until faulty resources are available again. Very often, when problems occur, developers are a bit cold to change their code because the fixes always seem very intrusive in the existing source code. For databases availability concerns, there is no magic, as prerequisites the processing operations should be implemented with transactions, for example through idempotent “Units Of Work”. For APIs, the problem is very different, because the transaction is the responsibility of the remote service. For APIs, something is possible.

I will show here that it is possible to implement a very simple logic of retry, without compromising the existing code.

Expressions are our friends…

private readonly Action<int, int, Action> _retry = (nb, ms, action) =>
{
    var bypass = new EventWaitHandle(false, EventResetMode.ManualReset);
    var count = 0;

    do
    {
        try
        {
            Console.WriteLine(@"{0} Trying to invoke : {1}", DateTime.Now, action);

            action.Invoke();
            bypass.Set();
        }
        catch (Exception ex)
        {
            Console.WriteLine(@"{0} Too bad ! {1}", DateTime.Now, ex.Message);

            if (++count > nb)
            {
                bypass.Set();
                throw;
            }
        }
    } while (!bypass.WaitOne(ms));
};

How to use it ? Let’s say we have to invoke a remote API, that enumerates all contracts that are related to a client. Let’s suppose the network, or the API, periodically encounters availability problems. The code below illustrates how to retry 5 times, waiting 2 seconds between each try :

var clientId = @"ref-00001-2017";
var contractsIds = new List<string>();

_retry.Invoke(5, 2000, () =>
{
    contractsIds = new ContractsRestInvoker().Invoke(clientId);
});

After 5 retries, the connectivity problem is considered as serious, so the code throws its exception.

You should keep in mind that adopting an agressive retry policy could make things much worst. Stressing faulty resources is never a good thing, as it increases pressure on them.

Add a Comment

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

− 6 = 3