promise-fn-retry
Version:
A simple retry to be used in integrations with NodeJS
116 lines (95 loc) • 3.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Default options to options param on retry function
*/
var defaultOptions = {
times: 1,
// Default retries
initialDelayTime: 100,
// Initial delay to first retry (ms)
onRetry: null,
// Function called in all retries. Is good to metrics, for example
shouldRetry: null // Verify if is necessary to call retry. Is good to API error of auth.
};
/**
* Internal controls
*/
var controlOptions = {
retained: 0,
// retries already made
currentDelay: null // current delay that used in current retry
};
/**
* Build the options parsed object in order
*/
var buildOptionsParsed = function buildOptionsParsed(options) {
return _objectSpread(_objectSpread(_objectSpread({}, defaultOptions), controlOptions), options);
};
/**
* Used to calc new delay on the next retry
* Today, this lib double the currentDelay
*/
var calcNewDelay = function calcNewDelay(currentDelay) {
return currentDelay * 2;
};
/**
* Build the options to retry object
* This count the retry
* This calculate the new delay
*/
var buildOptionsToRetry = function buildOptionsToRetry(optionsParsed) {
var currentDelay = optionsParsed.currentDelay,
initialDelayTime = optionsParsed.initialDelayTime,
retained = optionsParsed.retained;
return _objectSpread(_objectSpread({}, optionsParsed), {}, {
retained: retained + 1,
currentDelay: currentDelay ? calcNewDelay(currentDelay) : initialDelayTime
});
};
/**
* Verify if this lib should retry again
*/
var shouldRetryByExecutedTimes = function shouldRetryByExecutedTimes(_ref) {
var retained = _ref.retained,
times = _ref.times;
return retained < times;
};
/**
* Use the setTimeout to delay retry
*/
var delay = function delay(delayTime) {
return new Promise(function (resolve) {
return setTimeout(resolve, delayTime);
});
};
/**
* This run the lib
* Receive the promiseFn
*/
var retry = function retry(requestFn) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultOptions;
var optionsParsed = buildOptionsParsed(options);
var onRetry = optionsParsed.onRetry,
shouldRetry = optionsParsed.shouldRetry;
var promise = requestFn();
return promise["catch"](function (err) {
if (shouldRetryByExecutedTimes(optionsParsed) && (!shouldRetry || shouldRetry(err))) {
var optionsToRetry = buildOptionsToRetry(optionsParsed);
return delay(optionsToRetry.currentDelay).then(function () {
if (onRetry) onRetry(err, _objectSpread({}, optionsParsed));
return retry(requestFn, optionsToRetry);
});
}
throw err;
});
};
var _default = retry;
exports["default"] = _default;
module.exports = exports.default;