Skip to content

Instantly share code, notes, and snippets.

@guitarrapc
Last active June 1, 2022 10:40
Show Gist options
  • Save guitarrapc/1b06532e426e5d1844e89349b6519d8d to your computer and use it in GitHub Desktop.
Save guitarrapc/1b06532e426e5d1844e89349b6519d8d to your computer and use it in GitHub Desktop.
ExponentialBackoff Implemantation via C#.
async Task Main()
{
// minimum implemetation
try
{
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var retries = 0;
var maxRetry = 10;
do
{
Console.WriteLine($"Simple. retries: {retries}");
await Task.Delay((Math.Min((int)Math.Pow(2, retries), maxRetry) * 1000), cts.Token);
} while (retries++ < 10);
}
catch (TaskCanceledException ex)
{
Console.WriteLine("timeout reached.");
}
// with ExponentialBackoff class
try
{
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var limit = 0;
var exponentialBackoff = new ExponentialBackoff(100, 5000);
while (limit++ < 10)
{
Console.WriteLine($"Class. retries: {exponentialBackoff.Retries}");
await exponentialBackoff.DelayAsync(cts.Token);
}
}
catch (TaskCanceledException ex)
{
Console.WriteLine("timeout reached.");
}
}
public class ExponentialBackoff
{
private readonly int _delayMilliseconds;
private readonly int _maxDelayMilliseconds;
public int Retries => _retries;
private int _retries;
private int _pow;
public ExponentialBackoff(int delayMilliseconds, int maxDelayMilliseconds)
{
_delayMilliseconds = delayMilliseconds;
_maxDelayMilliseconds = maxDelayMilliseconds;
_retries = 0;
_pow = 0;
}
public async ValueTask DelayAsync(CancellationToken ct = default)
{
Interlocked.Increment(ref _retries);
if (_retries < 31)
{
Interlocked.Increment(ref _pow);
}
var delay = (Math.Min(_delayMilliseconds * (int)Math.Pow(2, _pow - 1), _maxDelayMilliseconds));
await Task.Delay(delay, ct).ConfigureAwait(false);
}
}
Simple. retries: 0
Simple. retries: 1
Simple. retries: 2
Simple. retries: 3
timeout reached.
Class. retries: 0
Class. retries: 1
Class. retries: 2
Class. retries: 3
Class. retries: 4
Class. retries: 5
Class. retries: 6
timeout reached.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment