rx-retry
Version:
Package for retries in RxJS, Promises and NestJS
43 lines • 2.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.retryBackoff = exports.resetIndexOnSuccess = exports.backoffDelayWithRandom = exports.exponentialBackoffDelay = exports.getDelay = void 0;
const rxjs_1 = require("rxjs");
function getDelay(backoffDelay, maxInterval) {
return Math.min(backoffDelay, maxInterval);
}
exports.getDelay = getDelay;
function exponentialBackoffDelay(iteration, initialInterval) {
return Math.pow(2, iteration) * initialInterval;
}
exports.exponentialBackoffDelay = exponentialBackoffDelay;
function backoffDelayWithRandom(iteration, initialInterval) {
const target = Math.pow(2, iteration) * initialInterval;
const toWait = Math.random() * target;
return toWait;
}
exports.backoffDelayWithRandom = backoffDelayWithRandom;
function resetIndexOnSuccess(isReset, index) {
return isReset ? 0 : index;
}
exports.resetIndexOnSuccess = resetIndexOnSuccess;
/**
* An operator for RxJS pipe, that retry with exponential backoff / random exponential backoff OR custom function.
* @param config - Configuration for retry, can be number as the initial interval, OR RetryBackoffConfig
*/
function retryBackoff(config) {
const { initialInterval, maxRetries = Infinity, maxInterval = Infinity, shouldRetry = () => true, resetOnSuccess = false, onFail = () => { }, onRetry = () => { }, backoffDelay = exponentialBackoffDelay, } = typeof config === 'number' ? { initialInterval: config } : config;
return (source) => (0, rxjs_1.defer)(() => {
let index = 0;
return source.pipe((0, rxjs_1.retryWhen)((errors) => errors.pipe((0, rxjs_1.concatMap)((error) => {
const attempt = index++;
return (0, rxjs_1.iif)(() => attempt < maxRetries && shouldRetry(error), (0, rxjs_1.timer)(getDelay(backoffDelay(attempt, initialInterval), maxInterval)).pipe((0, rxjs_1.tap)(() => onRetry(attempt + 1, error))), (0, rxjs_1.throwError)(error));
}), (0, rxjs_1.catchError)((error) => {
onFail(error);
return (0, rxjs_1.throwError)(error);
}))), (0, rxjs_1.tap)(() => {
index = resetIndexOnSuccess(resetOnSuccess, index);
}));
});
}
exports.retryBackoff = retryBackoff;
//# sourceMappingURL=retry-backoff.js.map