summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Ianus <hire@alexianus.com>2016-05-18 15:31:38 -0400
committerAlex Ianus <hire@alexianus.com>2016-05-18 15:31:38 -0400
commitc99b97e20ef9e38f78da19f3a1fa48f6deda2c33 (patch)
tree9d12c92e89961a3fab5008422078217772d998ff
parent9f03d5d630e467d3d3ec995d3610b967458de387 (diff)
downloadasync-c99b97e20ef9e38f78da19f3a1fa48f6deda2c33.tar.gz
Allow custom retry interval
-rw-r--r--lib/retry.js26
-rw-r--r--mocha_test/retry.js26
2 files changed, 42 insertions, 10 deletions
diff --git a/lib/retry.js b/lib/retry.js
index df80383..4029e10 100644
--- a/lib/retry.js
+++ b/lib/retry.js
@@ -64,16 +64,20 @@ export default function retry(times, task, callback) {
var DEFAULT_TIMES = 5;
var DEFAULT_INTERVAL = 0;
-
var opts = {
times: DEFAULT_TIMES,
- interval: DEFAULT_INTERVAL
+ intervalFunc: constantIntervalFunc(DEFAULT_INTERVAL)
};
function parseTimes(acc, t) {
if (typeof t === 'object') {
acc.times = +t.times || DEFAULT_TIMES;
- acc.interval = +t.interval || DEFAULT_INTERVAL;
+
+ if (typeof t.interval === 'function') {
+ acc.intervalFunc = t.interval;
+ } else {
+ acc.intervalFunc = constantIntervalFunc(+t.interval || DEFAULT_INTERVAL);
+ }
} else if (typeof t === 'number' || typeof t === 'string') {
acc.times = +t || DEFAULT_TIMES;
} else {
@@ -95,13 +99,13 @@ export default function retry(times, task, callback) {
throw new Error("Invalid arguments for async.retry");
}
-
var attempts = [];
- while (opts.times) {
- var isFinalAttempt = !(opts.times -= 1);
+ for (var i = 1; i < opts.times + 1; i++) {
+ var isFinalAttempt = (i == opts.times);
attempts.push(retryAttempt(isFinalAttempt));
- if (!isFinalAttempt && opts.interval > 0) {
- attempts.push(retryInterval(opts.interval));
+ var interval = opts.intervalFunc(i);
+ if (!isFinalAttempt && interval > 0) {
+ attempts.push(retryInterval(interval));
}
}
@@ -129,4 +133,10 @@ export default function retry(times, task, callback) {
}, interval);
};
}
+
+ function constantIntervalFunc(interval) {
+ return function() {
+ return interval;
+ };
+ }
}
diff --git a/mocha_test/retry.js b/mocha_test/retry.js
index 2aa48e8..43a8f6f 100644
--- a/mocha_test/retry.js
+++ b/mocha_test/retry.js
@@ -23,7 +23,7 @@ describe("retry", function () {
});
});
- it('retry when all attempts succeeds',function(done) {
+ it('retry when all attempts fail',function(done) {
var times = 3;
var callCount = 0;
var error = 'ERROR';
@@ -53,7 +53,7 @@ describe("retry", function () {
done();
});
- it('retry with interval when all attempts succeeds',function(done) {
+ it('retry with interval when all attempts fail',function(done) {
var times = 3;
var interval = 50;
var callCount = 0;
@@ -75,6 +75,28 @@ describe("retry", function () {
});
});
+ it('retry with custom interval when all attempts fail',function(done) {
+ var times = 3;
+ var intervalFunc = function(retryCount) { return retryCount * 100; };
+ var callCount = 0;
+ var error = 'ERROR';
+ var erroredResult = 'RESULT';
+ function fn(callback) {
+ callCount++;
+ callback(error + callCount, erroredResult + callCount); // respond with indexed values
+ }
+ var start = new Date().getTime();
+ async.retry({ times: times, interval: intervalFunc}, fn, function(err, result){
+ var now = new Date().getTime();
+ var duration = now - start;
+ assert(duration >= 300, 'did not include custom interval');
+ assert.equal(callCount, 3, "did not retry the correct number of times");
+ assert.equal(err, error + times, "Incorrect error was returned");
+ assert.equal(result, erroredResult + times, "Incorrect result was returned");
+ done();
+ });
+ });
+
it("should not require a callback", function (done) {
var called = false;
async.retry(3, function(cb) {