Polly C# retry exponentially for 3 tries then switch to retrying every hour

1.7k views Asked by At

I am trying to use polly to construct a policy that can retry exponentially for n tries and then switch to retrying every 1 hour. Can this be achieved?

I tried policy Wrap but did not get the desired results

2

There are 2 answers

0
Guru Stron On BEST ANSWER

This should be possible to achieve with overloads accepting custom sleepDurationProvider. For example something like the following:

var waitAndRetry = Policy
    .Handle<SomeException>()
    .WaitAndRetry(4, retryAttempt => retryAttempt switch // or WaitAndRetryForever
    {
        <= 3 => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), // for example n == 3
        _ => TimeSpan.FromHours(1)
    });
4
Peter Csala On

I might be late to the party but let me share my thoughts:

construct a policy that can retry exponentially for n tries Here is an example how you can construct

var retryWithBackoff = Policy
    .Handle<Exception>()
    .WaitAndRetryAsync(Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromSeconds(1), n));
  • You need to use the Polly.Contrib.WaitAndRetry to be able to use DecorrelatedJitterBackoffV2
    • Here you can find a good explanation how does this exponential backoff with jitter work
    • Please adjust the medianFirstRetryDelay parameter for your needs
  • Please also adjust the trigger for your need

retrying every 1 hour

var retryForeverWithAnHourDelay = Policy
    .Handle<Exception>()
    .WaitAndRetryForeverAsync(_ => TimeSpan.FromHours(1));
  • I've used retry forever because based on your requirements it seems like you want to retry until it succeeds
  • I've used async to avoid blocking for an hour while the policy sleeps

I tried policy Wrap

var combinedRetryPolicy = Policy.WrapAsync(retryForeverWithAnHourDelay, retryWithBackoff);
  • Please note the ordering
    • the left hand side parameter is the outer policy
    • the right hand side parameter is the inner policy
  • In other words if retryWithBackoff did not success then try retryForeverWithAnHourDelay

Here you can find a simple dotnet fiddle app which demonstrates this at work:


Final thoughts

Even though it is feasible to sleep for an hour with Polly, it is not suggested. Polly's retry was primarily designed to overcome transient failures. These failures should vanish/self-heal in minutes (not in hours or days).

If you need to wait that long I would rather suggest to use some sort of job scheduler like Quartz.NET or Hangfire.