1 function RetryOperation(timeouts, options) {
2 // Compatibility for the old (timeouts, retryForever) signature
3 if (typeof options === 'boolean') {
4 options = { forever: options };
7 this._timeouts = timeouts;
8 this._options = options || {};
12 this._operationTimeout = null;
13 this._operationTimeoutCb = null;
16 if (this._options.forever) {
17 this._cachedTimeouts = this._timeouts.slice(0);
20 module.exports = RetryOperation;
22 RetryOperation.prototype.stop = function() {
24 clearTimeout(this._timeout);
28 this._cachedTimeouts = null;
31 RetryOperation.prototype.retry = function(err) {
33 clearTimeout(this._timeout);
40 this._errors.push(err);
42 var timeout = this._timeouts.shift();
43 if (timeout === undefined) {
44 if (this._cachedTimeouts) {
45 // retry forever, only keep last error
46 this._errors.splice(this._errors.length - 1, this._errors.length);
47 this._timeouts = this._cachedTimeouts.slice(0);
48 timeout = this._timeouts.shift();
55 var timer = setTimeout(function() {
58 if (self._operationTimeoutCb) {
59 self._timeout = setTimeout(function() {
60 self._operationTimeoutCb(self._attempts);
61 }, self._operationTimeout);
63 if (this._options.unref) {
64 self._timeout.unref();
68 self._fn(self._attempts);
71 if (this._options.unref) {
78 RetryOperation.prototype.attempt = function(fn, timeoutOps) {
82 if (timeoutOps.timeout) {
83 this._operationTimeout = timeoutOps.timeout;
86 this._operationTimeoutCb = timeoutOps.cb;
91 if (this._operationTimeoutCb) {
92 this._timeout = setTimeout(function() {
93 self._operationTimeoutCb();
94 }, self._operationTimeout);
97 this._fn(this._attempts);
100 RetryOperation.prototype.try = function(fn) {
101 console.log('Using RetryOperation.try() is deprecated');
105 RetryOperation.prototype.start = function(fn) {
106 console.log('Using RetryOperation.start() is deprecated');
110 RetryOperation.prototype.start = RetryOperation.prototype.try;
112 RetryOperation.prototype.errors = function() {
116 RetryOperation.prototype.attempts = function() {
117 return this._attempts;
120 RetryOperation.prototype.mainError = function() {
121 if (this._errors.length === 0) {
126 var mainError = null;
127 var mainErrorCount = 0;
129 for (var i = 0; i < this._errors.length; i++) {
130 var error = this._errors[i];
131 var message = error.message;
132 var count = (counts[message] || 0) + 1;
134 counts[message] = count;
136 if (count >= mainErrorCount) {
138 mainErrorCount = count;