Skip to content

Commit

Permalink
feat(retry-forever): allow option to retry forever
Browse files Browse the repository at this point in the history
This provides a new option to retry to conditionally allow retrying
forever. I've chosen not to override the 'retries' options with
e.g. Infinity so that the user can still have a modicum of control
over the retry process in this particular scenario.
  • Loading branch information
mbroadst committed Jun 15, 2015
1 parent b254e59 commit 08de0fe
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
6 changes: 4 additions & 2 deletions lib/retry.js
@@ -1,8 +1,10 @@
var RetryOperation = require('./retry_operation');

exports.operation = function(options) {
var retryForever = false;
if (options && options.forever === true) retryForever = true;
var timeouts = exports.timeouts(options);
return new RetryOperation(timeouts);
return new RetryOperation(timeouts, retryForever);
};

exports.timeouts = function(options) {
Expand Down Expand Up @@ -47,4 +49,4 @@ exports._createTimeout = function(attempt, opts) {
timeout = Math.min(timeout, opts.maxTimeout);

return timeout;
};
};
15 changes: 12 additions & 3 deletions lib/retry_operation.js
@@ -1,11 +1,15 @@
function RetryOperation(timeouts) {
function RetryOperation(timeouts, retryForever) {
this._timeouts = timeouts;
this._fn = null;
this._errors = [];
this._attempts = 1;
this._operationTimeout = null;
this._operationTimeoutCb = null;
this._timeout = null;

if (!!retryForever) {
this._cachedTimeouts = this._timeouts.slice(0);
}
}
module.exports = RetryOperation;

Expand All @@ -22,7 +26,12 @@ RetryOperation.prototype.retry = function(err) {

var timeout = this._timeouts.shift();
if (timeout === undefined) {
return false;
if (this._cachedTimeouts) {
this._timeouts = this._cachedTimeouts.slice(0);
timeout = this._timeouts.shift();
} else {
return false;
}
}

this._attempts++;
Expand Down Expand Up @@ -106,4 +115,4 @@ RetryOperation.prototype.mainError = function() {
}

return mainError;
};
};
28 changes: 27 additions & 1 deletion test/integration/test-retry-operation.js
Expand Up @@ -77,4 +77,30 @@ var retry = require(common.dir.lib + '/retry');
};

fn();
})();
})();

(function testRetryForever() {
var error = new Error('some error');
var operation = retry.operation({ retries: 3, forever: true });
var attempts = 0;

var finalCallback = fake.callback('finalCallback');
fake.expectAnytime(finalCallback);

var fn = function() {
operation.attempt(function(currentAttempt) {
attempts++;
assert.equal(currentAttempt, attempts);
if (attempts !== 6 && operation.retry(error)) {
return;
}

assert.strictEqual(attempts, 6);
assert.strictEqual(operation.attempts(), attempts);
assert.strictEqual(operation.mainError(), error);
finalCallback();
});
};

fn();
})();

1 comment on commit 08de0fe

@satazor
Copy link
Contributor

@satazor satazor commented on 08de0fe Jan 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this option is not documented :(

Please sign in to comment.