Skip to content

Instantly share code, notes, and snippets.

@admir-live
Created February 29, 2024 23:46
Show Gist options
  • Select an option

  • Save admir-live/f8aa370f4e29a18ac78fed3339af9f1e to your computer and use it in GitHub Desktop.

Select an option

Save admir-live/f8aa370f4e29a18ac78fed3339af9f1e to your computer and use it in GitHub Desktop.
ExponentialBackoff.cs
public sealed class ExponentialBackoff
{
private const double InitialDelayInSeconds = 1;
private const double MaximumDelayInSeconds = 60;
public static async Task<T> ExecuteWithExponentialBackoffAsync<T>(Func<Task<T>> operation, int maximumRetryAttempts = 5)
{
int currentRetryCount = 0;
double currentDelayInSeconds = InitialDelayInSeconds;
while (currentRetryCount <= maximumRetryAttempts)
{
try
{
return await operation();
}
catch (Exception)
{
if (currentRetryCount == maximumRetryAttempts)
{
throw;
}
await ApplyDelayWithJitter(currentDelayInSeconds);
currentRetryCount++;
currentDelayInSeconds = CalculateNextDelay(currentDelayInSeconds);
}
}
throw new InvalidOperationException("Exceeded maximum retry attempts");
}
private static async Task ApplyDelayWithJitter(double currentDelay)
{
double jitter = (0.5 - Random.Shared.NextDouble()) * currentDelay;
double totalWaitTimeInSeconds = Math.Min(MaximumDelayInSeconds, currentDelay + jitter);
await Task.Delay(TimeSpan.FromSeconds(totalWaitTimeInSeconds));
}
private static double CalculateNextDelay(double currentDelay)
{
return Math.Min(currentDelay * 2, MaximumDelayInSeconds);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment