1
Vote

ExponentialBackoff retry strategy integer overflow

description

http://topaz.codeplex.com/SourceControl/latest#source/Source/TransientFaultHandling/ExponentialBackoff.cs breaks down with an unchecked integer overflow due to casting the delta to an int.

Plug in for example the following constants:

deltaBackoff = 1s
minBackoff = 1s
maxBackoff = 60s

retry delta (ms) interval (ms)
1 1086 2086
2 2979 3979
3 5635 6635
4 16815 17815
5 26288 27288
6 74466 60000
7 129413 60000
8 283050 60000
9 542171 60000
10 874665 60000
11 1678540 60000
12 3714165 60000
13 8805325 60000
14 14810232 60000
15 35290059 60000
16 54262980 60000
17 154925922 60000
18 276036579 60000
19 457702551 60000
20 991951950 60000
21 -2147483648 -2147482648 <- integer overflow
...

Which means that after the 20th retry the interval becomes 0 and goes into a busy loop, assuming you're allowing enough retries.

The fix is to remove the cast to int, i.e.:

var delta = (int)((Math.Pow(2.0, currentRetryCount) - 1.0) ...

should be

var delta = (Math.Pow(2.0, currentRetryCount) - 1.0) ...

The 'checked' block on interval is also redundant:

var interval = (int)Math.Min(checked(this.minBackoff.TotalMilliseconds + delta), this.maxBackoff.TotalMilliseconds);

could be:

var interval = (int)Math.Min(this.minBackoff.TotalMilliseconds + delta, this.maxBackoff.TotalMilliseconds);

since as delta approaches Infinity, Math.Min will just return maxBackoff.

comments