Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 417
eti aggarwal Avatar asked Sep 07 '25 18:09

eti aggarwal


2 Answers

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)
    });
like image 146
Guru Stron Avatar answered Sep 09 '25 08:09

Guru Stron


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:

  • https://dotnetfiddle.net/OQihRk
  • Please note that dotnet fiddle will terminate the app after 10 seconds

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.

like image 21
Peter Csala Avatar answered Sep 09 '25 06:09

Peter Csala