Skip to content

Instantly share code, notes, and snippets.

@muendelezaji
Last active November 21, 2016 06:09
Show Gist options
  • Save muendelezaji/ce3878d1ce9617a4e42a25d7aa755ef3 to your computer and use it in GitHub Desktop.
Save muendelezaji/ce3878d1ce9617a4e42a25d7aa755ef3 to your computer and use it in GitHub Desktop.
Exponential backoff strategy for a generic asynchronous function call
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Retry with Backoff</title>
</head>
<body>
<pre id="result"></pre>
</body>
</html>
// JSFiddle - https://jsfiddle.net/mdzj/dwwx0889
// Inspired by https://jsfiddle.net/pajtai/pLka0ow9
// HTML: <pre id="result"></pre>
// main
retryWithBackoff(sometimesFailsAsync, 10, 1000, 30000, function (error, result) {
console.log('final result is', error ? error : result);
});
var percentFail = 0.8;
// Replace default
console.log = consoleLog;
function consoleLog() {
var args = [].slice.apply(arguments);
args.unshift((new Date()).toISOString()); // prepend date
document.querySelector('#result').innerHTML += '\n' + args.join(' - ');
}
function sometimesFailsAsync (callback) {
var asyncDelay = Math.floor(Math.random() * 5000);
console.log('async delay', asyncDelay);
setTimeout(function () {
var value = Math.random();
if (value >= percentFail) {
error = null;
result = 'success = ' + value;
} else {
error = new Error('failed = ' + value);
result = null;
}
return callback(error, result);
}, asyncDelay);
}
function retryWithBackoff (func, attempts, minWait, maxWait, callback) {
var wait = +minWait || 100; // first wait will be 100ms if not specified
var retry = function (fn, cb) {
console.log('retries left', attempts, 'next try in', wait);
setTimeout(function () { return fn(cb); }, wait); // retry after wait time elapsed
wait = wait < maxWait / 2 ? wait * 2 : maxWait; // increase wait time for next attempt
}
var repeater = function (error, result) {
if (!error) {
return callback(null, result);
} else {
if (attempts-- > 0) {
return retry(func, repeater);
} else {
return callback(error); // 0 attempts left, give up
}
}
}
console.log('starting...');
return func(repeater);
}
@muendelezaji
Copy link
Author

@muendelezaji
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment