Skip to content

Instantly share code, notes, and snippets.

@vernig
Created August 18, 2021 12:59
Show Gist options
  • Save vernig/6226b218959ec64c67ceaa323bb16e7f to your computer and use it in GitHub Desktop.
Save vernig/6226b218959ec64c67ceaa323bb16e7f to your computer and use it in GitHub Desktop.
var maxBackoff = 5000;
var expBackoffLogs = [];
function tryWithTimeout(testFunction, argument, timeout) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, timeout);
}).then(() => {
expBackoffLogs.push(
`tryWithTimeout: Trying ${argument} with timeout ${timeout}`
);
return testFunction(argument)
.then((result) => Promise.resolve(result))
.catch((error) => {
if (timeout * 2 > maxBackoff) {
return Promise.reject(
new Error('mximum_backoff reached on number ' + argument)
);
} else if (error.status === 429) {
expBackoffLogs.push(
'tryWithTimeout: Got 429 error with number ' +
argument +
'. Trying again...'
);
return tryWithTimeout(
testFunction,
argument,
(timeout ? Math.trunc(timeout) * 2 : 1000) + Math.random() * 1000
);
} else {
return Promise.reject(error);
}
});
});
}
/**
* Perform requests in fn on the dataSet using exponential backoff algorithm
*
* @param {Promise<any>} fn Function to execute the request. It needs to be a promise
* @param {Array} dataSet Array of argument to be executing the function on
* @param {Number} maximumBackoff Time (in millisecond) after which the function is not excecuted again
*
* @returns {Promise<any>} Return a Promise with the array of the results returned by each fn execution
*/
function exponentialBackoff(fn, dataSet, maximumBackoff) {
if (maximumBackoff) {
maxBackoff = maximumBackoff;
}
expBackoffLogs = [];
return Promise.all(
dataSet.map((argument) => tryWithTimeout(fn, argument, 0))
).then((results) => {
expBackoffLogs.push('Execution completed');
return Promise.resolve(results);
})
.catch(error => {
expBackoffLogs.push('Error in executing exponential backoff', error);
return Promise.reject(error);
})
}
module.exports = exponentialBackoff;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment