diff options
author | Alex Ianus <hire@alexianus.com> | 2016-05-18 15:31:38 -0400 |
---|---|---|
committer | Alex Ianus <hire@alexianus.com> | 2016-05-18 15:31:38 -0400 |
commit | c99b97e20ef9e38f78da19f3a1fa48f6deda2c33 (patch) | |
tree | 9d12c92e89961a3fab5008422078217772d998ff | |
parent | 9f03d5d630e467d3d3ec995d3610b967458de387 (diff) | |
download | async-c99b97e20ef9e38f78da19f3a1fa48f6deda2c33.tar.gz |
Allow custom retry interval
-rw-r--r-- | lib/retry.js | 26 | ||||
-rw-r--r-- | mocha_test/retry.js | 26 |
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) { |