mongo/jstests/libs/run_with_retries.js

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");
}