@daisugi/kintsugi
Version:
Kintsugi is a set of utilities to help build a fault tolerant services.
48 lines • 2.09 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateRetryDelayMs = calculateRetryDelayMs;
exports.shouldRetry = shouldRetry;
exports.withRetry = withRetry;
const ayamari_1 = require("@daisugi/ayamari");
const random_between_js_1 = require("./random_between.js");
const wait_for_js_1 = require("./wait_for.js");
const defaultFirstDelayMs = 200;
const defaultMaxDelayMs = 600;
const defaultTimeFactor = 2;
const defaultMaxRetries = 3;
function calculateRetryDelayMs(firstDelayMs, maxDelayMs, timeFactor, retryNumber) {
const delayMs = Math.min(maxDelayMs, firstDelayMs * timeFactor ** retryNumber);
/** Full jitter https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ */
const delayWithJitterMs = (0, random_between_js_1.randomBetween)(0, delayMs);
return delayWithJitterMs;
}
function shouldRetry(response, retryNumber, maxRetries) {
if (response.isFailure) {
if (response.getError().code ===
ayamari_1.Ayamari.errCode.CircuitSuspended) {
return false;
}
if (retryNumber < maxRetries) {
return true;
}
}
return false;
}
function withRetry(fn, opts = {}) {
const firstDelayMs = opts.firstDelayMs || defaultFirstDelayMs;
const maxDelayMs = opts.maxDelayMs || defaultMaxDelayMs;
const timeFactor = opts.timeFactor || defaultTimeFactor;
const maxRetries = opts.maxRetries || defaultMaxRetries;
const _calculateRetryDelayMs = opts.calculateRetryDelayMs || calculateRetryDelayMs;
const _shouldRetry = opts.shouldRetry || shouldRetry;
async function fnWithRetry(fn, args, retryNumber) {
const response = await fn.call(this, args);
if (_shouldRetry(response, retryNumber, maxRetries)) {
await (0, wait_for_js_1.waitFor)(_calculateRetryDelayMs(firstDelayMs, maxDelayMs, timeFactor, retryNumber));
return fnWithRetry(fn, args, retryNumber + 1);
}
return response;
}
return (...args) => fnWithRetry(fn, args, 0);
}
//# sourceMappingURL=with_retry.js.map