I implemented the following formula found on Wikipedia in C#.
Furthermore, I added the ability to set a maximum delay that is quite useful when you want to control your delays. The calculated delay is in seconds.
public static class DelayCalculator { public static Int64 ExponentialDelay(int failedAttempts, int maxDelayInSeconds = 1024) { //Attempt 1 0s 0s //Attempt 2 2s 2s //Attempt 3 4s 4s //Attempt 4 8s 8s //Attempt 5 16s 16s //Attempt 6 32s 32s //Attempt 7 64s 1m 4s //Attempt 8 128s 2m 8s //Attempt 9 256s 4m 16s //Attempt 10 512 8m 32s //Attempt 11 1024 17m 4s //Attempt 12 2048 34m 8s //Attempt 13 4096 1h 8m 16s //Attempt 14 8192 2h 16m 32s //Attempt 15 16384 4h 33m 4s var delayInSeconds = ((1d / 2d) * (Math.Pow(2d, failedAttempts) - 1d)); return maxDelayInSeconds < delayInSeconds ? Convert.ToInt64(maxDelayInSeconds) : Convert.ToInt64(delayInSeconds); } }
The code from this Post is part of the Brisebois.WindowsAzure NuGet Package
To install Brisebois.WindowsAzure, run the following command in the Package Manager Console
PM> Install-Package Brisebois.WindowsAzure
Actually I use a Fibonacci formula for something like this but I don’t think one is better than the other. Chances that an operation could fail every 2 seconds exactly (which is a fraction of the delay of every attempts using your exponential formula) are pretty slim.
LikeLike
Non-memoized Fibonacci / and Math.Pow can be rather expensive… Why not use delay = (delay + 1) << 1 or some such?
LikeLike
Agreed, I could use a materialized array of delays.
The point is to have many clients disynchronized as to not cause Retry storms. This only one of many solutions.
LikeLiked by 1 person