Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created February 23, 2018 11:59
Show Gist options
  • Save bennadel/2b3a718373a6168a8000a3f762077b09 to your computer and use it in GitHub Desktop.
Save bennadel/2b3a718373a6168a8000a3f762077b09 to your computer and use it in GitHub Desktop.
Creating A Poor Man's Exponential Backoff And Retry Algorithm In Legacy Code Using ColdFusion
<cfscript>
doTheThing( 4 );
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
/**
* I do the thing that requires a brittle network connection. I will retry failed
* connections using a reasonable backoff; and, eventually throw an error if none
* of the retries are successful.
*
* @id I am the data thing.
* @output false
*/
public void function doTheThing( required numeric id ) {
// Rather than relying on the maths to do backoff calculations, this collection
// provides an explicit set of backoff values (in milliseconds). This collection
// also doubles as the number of attempts that we should execute against the
// remote API.
// --
// NOTE: Some randomness will be applied to these values as execution time.
var backoffDurations = [
1000,
2000,
4000,
8000,
16000,
32000,
64000,
0 // Indicates that the last timeout should be recorded as an error.
];
for ( var backoffDuration in backoffDurations ) {
try {
makeApiRequest( id );
// If we made it this far, the API request didn't throw an error, which
// means that it was successful; return out of the method and retry-loop.
return;
} catch ( any error ) {
// If the error is a retriable error AND we still have a non-zero backoff
// to consume, sleep the thread and try the request again.
if ( isRetrialbeError( error ) && backoffDuration ) {
sleep( applyJitter( backoffDuration ) );
// Otherwise, we can't recover from this error, so let it bubble up.
} else {
rethrow;
}
}
}
}
/**
* I apply a 20% jitter to a given backoff value in order to ensure some kind of
* randomness to the collection of requests that may stampede towards an API.
*
* @value I am the backoff time being nudged.
* @output false
*/
public numeric function applyJitter( required numeric value ) {
// Create a jitter of +/- 20%.
var jitter = ( randRange( 80, 120 ) / 100 );
return( fix( value * jitter ) );
}
</cfscript>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment