An exponential back-off implementation I used somewhere; probably room for improvement, but it works good enough.
Posted by jpluimers on 2017/01/17
I will probably need this again somewhere in the future: An exponential back-off implementation I used somewhere; probably room for improvement, but it works good enough.
It’s Delphi, but I’ve not seen practical implementations in C# either.
(the updated version thanks to Anders Melander).
–jeroen
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function TryGetLocationLockWithExponentialBackOff: Boolean; | |
| const | |
| cBase = 2; | |
| cMaxWaitMilliSeconds = 1500; | |
| var | |
| lWaitMilliSeconds: integer; | |
| begin | |
| Result := True; | |
| lWaitMilliSeconds := cBase; | |
| while (not TryGetLocationLock) do | |
| begin | |
| if (lWaitMilliSeconds > cMaxWaitMilliSeconds) then | |
| Exit(False); | |
| Sleep(lWaitMilliSeconds); | |
| Inc(lWaitMilliSeconds, lWaitMilliSeconds); | |
| end; | |
| end; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function TryGetLocationLockWithExponentialBackOff: Boolean; | |
| const | |
| cBase = 2; | |
| cMaxWaitMilliSeconds = 1500; | |
| var | |
| lIteration: Integer; | |
| lWaitMilliSeconds: Single; | |
| begin | |
| lIteration := 1; | |
| lWaitMilliSeconds := 0; | |
| while lWaitMilliSeconds < cMaxWaitMilliSeconds do | |
| begin | |
| Result := TryGetLocationLock; | |
| if Result then | |
| Exit; | |
| lWaitMilliSeconds := IntPower(cBase, lIteration); | |
| Inc(lIteration); | |
| Sleep(Round(lWaitMilliSeconds)); | |
| end; | |
| Result := TryGetLocationLock; | |
| end; |






bugcheck said
Nope; Wrong on both accounts.
I’m just attempting to acquire the lock before the test for time out instead of the reverse. The result is the same.
And I’m doubling the wait time using simple integer addition instead of using a floating point math function.
If you can’t grok the code you can easily run both versions in your head to verify. It’s not that many iterations: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048->exit = 11 attempts
Kevin G. McCoy said
Another way to do it is to left-shift the sleep time by one bit during each iteration.
David Moorhouse said
Nice work. BugCheck’s simplification omits the exponential part (simple linear progression instead) and omits the final call to TryGetLocationLock once the maximum wait time has been exceeded.
bugcheck said
Impressive piece of overengineering.
function TryGetLocationLockWithExponentialBackOff: Boolean;
const
cBase = 2;
cMaxWaitMilliSeconds = 1500;
var
lWaitMilliSeconds: integer;
begin
Result := True;
lWaitMilliSeconds := cBase;
while (not TryGetLocationLock) do
begin
if (lWaitMilliSeconds > cMaxWaitMilliSeconds) then
Exit(False);
Sleep(lWaitMilliSeconds);
Inc(lWaitMilliSeconds, lWaitMilliSeconds);
end;
end;
jpluimers said
Thanks for the update. I’ve added it to the gist and mentioned you in the article.