Created
August 18, 2021 12:59
-
-
Save vernig/6226b218959ec64c67ceaa323bb16e7f to your computer and use it in GitHub Desktop.
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
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