mirror of https://github.com/mongodb/mongo
38 lines
1.6 KiB
JavaScript
38 lines
1.6 KiB
JavaScript
/**
|
|
* Helper function for retrying execution of a callback function until success or a terminal error
|
|
* condition.
|
|
*/
|
|
|
|
/**
|
|
* Executes the callback function 'fn' until it succeeds (i.e. does not throw an exception), the
|
|
* maximum number of retry attempts is reached, or a terminal error condition is reached. Retries
|
|
* are executed using an expotentiall backoff. The maximum number of retries is configurable.
|
|
*
|
|
* @param {function} fn the callback to execute
|
|
* @param {function} shouldRetry a function to determine whether or not the execution should be
|
|
* retried. Receives a caught exception as an input and is supposed to return true for
|
|
* another retry attempt, and false otherwise.
|
|
* @param {number} maxRetries maximum number of attempts (including the first attempt).
|
|
* @param {number} initialBackoffMs initial value for expoential backoff in milliseconds.
|
|
*
|
|
* @return {any} the result of the callback function 'fn' on success, and an exception otherwise.
|
|
*/
|
|
export function runWithRetries(fn, shouldRetry, maxRetries = 3, initialBackoffMs = 100) {
|
|
let backoff = initialBackoffMs;
|
|
for (let attemptNumber = 1; attemptNumber <= maxRetries; attemptNumber++) {
|
|
try {
|
|
return fn();
|
|
} catch (e) {
|
|
jsTest.log(`runWithRetries: attempt ${attemptNumber} failed with error: ${tojson(e)}`);
|
|
if (attemptNumber === maxRetries || !shouldRetry(e)) {
|
|
throw e;
|
|
}
|
|
sleep(backoff);
|
|
backoff *= 2;
|
|
}
|
|
}
|
|
|
|
// Cannot get here.
|
|
throw new Error("runWithRetries: unreachable error");
|
|
}
|