@webex/common
Version:
Common utilities for Cisco Webex
128 lines (124 loc) • 5.48 kB
JavaScript
var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
_Object$defineProperty(exports, "__esModule", {
value: true
});
exports.default = retry;
var _apply = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/apply"));
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
var _events = require("events");
var _lodash = require("lodash");
var _backoff = _interopRequireDefault(require("backoff"));
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; } /*!
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
*/
/* eslint max-nested-callbacks: [0] */
/**
* Makes a promise-returning method retryable according to the specified backoff
* pattern
* @param {Object} options
* @param {boolean} options.backoff
* @param {number} options.delay
* @param {number} options.initialDelay
* @param {number} options.maxAttempts
* @param {number} options.maxDelay
*
* @returns {Function}
*/
function retry() {
for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) {
params[_key] = arguments[_key];
}
var options = params[0] || {};
options = _objectSpread({}, options);
(0, _lodash.defaults)(options, {
backoff: true,
delay: 1,
maxAttempts: 3
});
var strategyOptions;
if (options.backoff) {
strategyOptions = {
initialDelay: options.delay,
maxDelay: options.maxDelay
};
} else {
strategyOptions = {
initialDelay: 1,
maxDelay: 1
};
}
if (params.length === 3) {
return (0, _apply.default)(retryDecorator, null, params);
}
return retryDecorator;
/**
* @param {Object} target
* @param {string} prop
* @param {Object} descriptor
* @private
* @returns {Object}
*/
function retryDecorator(target, prop, descriptor) {
descriptor.value = (0, _lodash.wrap)(descriptor.value, function retryExecutor(fn) {
var _this = this;
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
var emitter = new _events.EventEmitter();
var promise = new _promise.default(function (resolve, reject) {
// backoff.call is not Function.prototype.call; it's an unfortunate naming
// collision.
/* eslint prefer-reflect: [0] */
var call = _backoff.default.call(function (cb) {
/* eslint no-invalid-this: [0] */
var innerPromise = (0, _apply.default)(fn, _this, args);
if ((0, _lodash.isFunction)(innerPromise.on)) {
innerPromise.on('progress', emitter.emit.bind(emitter, 'progress'));
innerPromise.on('upload-progress', emitter.emit.bind(emitter, 'upload-progress'));
innerPromise.on('download-progress', emitter.emit.bind(emitter, 'download-progress'));
}
return innerPromise.then(function (res) {
cb(null, res);
}).catch(function (reason) {
if (!reason) {
reason = new Error('retryable method failed without providing an error object');
}
cb(reason);
});
}, function (err, res) {
if (err) {
return reject(err);
}
return resolve(res);
});
call.setStrategy(new _backoff.default.ExponentialStrategy(strategyOptions));
if (options.maxAttempts) {
call.failAfter(options.maxAttempts - 1);
}
call.start();
});
promise.on = function on(key, callback) {
emitter.on(key, callback);
return promise;
};
return promise;
});
// This *should* make decorators compatible with AmpersandState class
// definitions
if ((0, _typeof2.default)(target) === 'object' && !target.prototype) {
target[prop] = descriptor.value;
}
return descriptor;
}
}
//# sourceMappingURL=retry.js.map
;