@aimee-blue/ab-service-kit
Version:
Aimee Blue Service Template
62 lines (51 loc) • 2.09 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.retryWithBackoff = retryWithBackoff;
var _rxjs = require("rxjs");
var _operators = require("rxjs/operators");
var _registerError = require("./registerError");
var _logging = require("./logging");
function timeBeforeNextRetry(opts, numberOfErrors) {
return opts.minWaitTime + (numberOfErrors === 1 ? opts.waitTimeOnFirstError : Math.min(opts.waitTimeOnBackoff * numberOfErrors, opts.maxWaitTime));
}
function retryWithBackoff(optsRaw) {
var _opts$logger;
const opts = {
shouldRetry: _info => {
return true;
},
resetErrorsOnNext: true,
waitTimeOnFirstError: 1 * 1000,
waitTimeOnBackoff: 5 * 1000,
minWaitTime: 1,
maxWaitTime: 1 * 60 * 60 * 1000,
sourceDescription: 'process',
...optsRaw
};
const logger = (_opts$logger = opts.logger) !== null && _opts$logger !== void 0 ? _opts$logger : (0, _logging.defaultBasicLogger)();
const log = info => {
logger.error(`💥 The ${opts.sourceDescription || 'process'} has failed ${info.numberOfErrors} time(s). Will retry in ${(info.timeBeforeNextRetry / 1000).toFixed(2)}s. `, info.error);
};
const recursiveObserve = (errors, source) => {
let reset = false;
return source.pipe(stream => opts.resetErrorsOnNext ? stream.pipe((0, _operators.tap)(() => {
// if we got at least one element consider this a success
reset = true;
})) : stream, (0, _operators.catchError)(error => {
(0, _registerError.registerError)(error);
const numberOfErrors = reset ? 0 : errors;
const time = timeBeforeNextRetry(opts, numberOfErrors + 1);
const info = {
error,
numberOfErrors: numberOfErrors + 1,
timeBeforeNextRetry: time
};
log(info);
return opts.shouldRetry(info) ? (0, _rxjs.timer)(time).pipe((0, _operators.switchMapTo)(recursiveObserve(numberOfErrors + 1, source))) : (0, _rxjs.from)(Promise.reject(error));
}));
};
return source => recursiveObserve(0, source);
}
//# sourceMappingURL=retryWithBackoff.js.map