Comparing version 0.10.1 to 0.12.0
@@ -7,4 +7,6 @@ function RetryOperation(timeouts, options) { | ||
this._originalTimeouts = JSON.parse(JSON.stringify(timeouts)); | ||
this._timeouts = timeouts; | ||
this._options = options || {}; | ||
this._maxRetryTime = options && options.maxRetryTime || Infinity; | ||
this._fn = null; | ||
@@ -16,2 +18,3 @@ this._errors = []; | ||
this._timeout = null; | ||
this._operationStart = null; | ||
@@ -24,2 +27,7 @@ if (this._options.forever) { | ||
RetryOperation.prototype.reset = function() { | ||
this._attempts = 1; | ||
this._timeouts = this._originalTimeouts; | ||
} | ||
RetryOperation.prototype.stop = function() { | ||
@@ -42,2 +50,7 @@ if (this._timeout) { | ||
} | ||
var currentTime = new Date().getTime(); | ||
if (err && currentTime - this._operationStart >= this._maxRetryTime) { | ||
this._errors.unshift(new Error('RetryOperation timeout occurred')); | ||
return false; | ||
} | ||
@@ -67,3 +80,3 @@ this._errors.push(err); | ||
if (this._options.unref) { | ||
if (self._options.unref) { | ||
self._timeout.unref(); | ||
@@ -102,2 +115,4 @@ } | ||
this._operationStart = new Date().getTime(); | ||
this._fn(this._attempts); | ||
@@ -104,0 +119,0 @@ }; |
@@ -7,3 +7,4 @@ var RetryOperation = require('./retry_operation'); | ||
forever: options && options.forever, | ||
unref: options && options.unref | ||
unref: options && options.unref, | ||
maxRetryTime: options && options.maxRetryTime | ||
}); | ||
@@ -79,5 +80,5 @@ }; | ||
obj[method] = function retryWrapper() { | ||
obj[method] = function retryWrapper(original) { | ||
var op = exports.operation(options); | ||
var args = Array.prototype.slice.call(arguments); | ||
var args = Array.prototype.slice.call(arguments, 1); | ||
var callback = args.pop(); | ||
@@ -98,5 +99,5 @@ | ||
}); | ||
}; | ||
}.bind(obj, original); | ||
obj[method].options = options; | ||
} | ||
}; |
@@ -6,3 +6,3 @@ { | ||
"license": "MIT", | ||
"version": "0.10.1", | ||
"version": "0.12.0", | ||
"homepage": "https://github.com/tim-kos/node-retry", | ||
@@ -18,3 +18,3 @@ "repository": { | ||
"engines": { | ||
"node": "*" | ||
"node": ">= 4" | ||
}, | ||
@@ -24,4 +24,12 @@ "dependencies": {}, | ||
"fake": "0.2.0", | ||
"far": "0.0.1" | ||
"istanbul": "^0.4.5", | ||
"tape": "^4.8.0" | ||
}, | ||
"scripts": { | ||
"test": "./node_modules/.bin/istanbul cover ./node_modules/tape/bin/tape ./test/integration/*.js", | ||
"release:major": "env SEMANTIC=major npm run release", | ||
"release:minor": "env SEMANTIC=minor npm run release", | ||
"release:patch": "env SEMANTIC=patch npm run release", | ||
"release": "npm version ${SEMANTIC:-patch} -m \"Release %s\" && git push && git push --tags && npm publish" | ||
} | ||
} |
@@ -0,1 +1,6 @@ | ||
<!-- badges/ --> | ||
[![Build Status](https://secure.travis-ci.org/tim-kos/node-retry.png?branch=master)](http://travis-ci.org/tim-kos/node-retry "Check this project's build status on TravisCI") | ||
[![codecov](https://codecov.io/gh/tim-kos/node-retry/branch/master/graph/badge.svg)](https://codecov.io/gh/tim-kos/node-retry) | ||
<!-- /badges --> | ||
# retry | ||
@@ -63,3 +68,4 @@ | ||
* `forever`: Whether to retry forever, defaults to `false`. | ||
* `unref`: Wether to [unref](https://nodejs.org/api/timers.html#timers_unref) the setTimeout's, defaults to `false`. | ||
* `unref`: Whether to [unref](https://nodejs.org/api/timers.html#timers_unref) the setTimeout's, defaults to `false`. | ||
* `maxRetryTime`: The maximum time (in milliseconds) that the retried operation is allowed to run. Default is `Infinity`. | ||
@@ -73,3 +79,3 @@ ### retry.timeouts([options]) | ||
* `retries`: The maximum amount of times to retry the operation. Default is `10`. | ||
* `retries`: The maximum amount of times to retry the operation. Default is `10`. Seting this to `1` means `do it once, then retry it once`. | ||
* `factor`: The exponential factor to use. Default is `2`. | ||
@@ -148,4 +154,6 @@ * `minTimeout`: The number of milliseconds before starting the first retry. Default is `1000`. | ||
Returns an array of all errors that have been passed to | ||
`retryOperation.retry()` so far. | ||
Returns an array of all errors that have been passed to `retryOperation.retry()` so far. The | ||
returning array has the errors ordered chronologically based on when they were passed to | ||
`retryOperation.retry()`, which means the first passed error is at index zero and the last is | ||
at the last index. | ||
@@ -191,2 +199,6 @@ #### retryOperation.mainError() | ||
#### retryOperation.reset() | ||
Resets the internal state of the operation object, so that you can call `attempt()` again as if this was a new operation object. | ||
#### retryOperation.attempts() | ||
@@ -193,0 +205,0 @@ |
@@ -6,2 +6,41 @@ var common = require('../common'); | ||
(function testReset() { | ||
var error = new Error('some error'); | ||
var operation = retry.operation([1, 2, 3]); | ||
var attempts = 0; | ||
var finalCallback = fake.callback('finalCallback'); | ||
fake.expectAnytime(finalCallback); | ||
var expectedFinishes = 1; | ||
var finishes = 0; | ||
var fn = function() { | ||
operation.attempt(function(currentAttempt) { | ||
attempts++; | ||
assert.equal(currentAttempt, attempts); | ||
if (operation.retry(error)) { | ||
return; | ||
} | ||
finishes++ | ||
assert.equal(expectedFinishes, finishes); | ||
assert.strictEqual(attempts, 4); | ||
assert.strictEqual(operation.attempts(), attempts); | ||
assert.strictEqual(operation.mainError(), error); | ||
if (finishes < 2) { | ||
attempts = 0; | ||
expectedFinishes++; | ||
operation.reset(); | ||
fn() | ||
} else { | ||
finalCallback(); | ||
} | ||
}); | ||
}; | ||
fn(); | ||
})(); | ||
(function testErrors() { | ||
@@ -57,3 +96,2 @@ var operation = retry.operation(); | ||
(function testRetry() { | ||
var times = 3; | ||
var error = new Error('some error'); | ||
@@ -137,3 +175,3 @@ var operation = retry.operation([1, 2, 3]); | ||
var maxTime = minTime + 20 // add a little headroom for code execution time | ||
assert(endTime > minTime) | ||
assert(endTime >= minTime) | ||
assert(endTime < maxTime) | ||
@@ -180,1 +218,45 @@ assert.strictEqual(attempts, 4); | ||
})(); | ||
(function testMaxRetryTime() { | ||
var error = new Error('some error'); | ||
var maxRetryTime = 30; | ||
var operation = retry.operation({ | ||
minTimeout: 1, | ||
maxRetryTime: maxRetryTime | ||
}); | ||
var attempts = 0; | ||
var finalCallback = fake.callback('finalCallback'); | ||
fake.expectAnytime(finalCallback); | ||
var longAsyncFunction = function (wait, callback){ | ||
setTimeout(callback, wait); | ||
}; | ||
var fn = function() { | ||
var startTime = new Date().getTime(); | ||
operation.attempt(function(currentAttempt) { | ||
attempts++; | ||
assert.equal(currentAttempt, attempts); | ||
if (attempts !== 2) { | ||
if (operation.retry(error)) { | ||
return; | ||
} | ||
} else { | ||
var curTime = new Date().getTime(); | ||
longAsyncFunction(maxRetryTime - (curTime - startTime - 1), function(){ | ||
if (operation.retry(error)) { | ||
assert.fail('timeout should be occurred'); | ||
return; | ||
} | ||
assert.strictEqual(operation.mainError(), error); | ||
finalCallback(); | ||
}); | ||
} | ||
}); | ||
}; | ||
fn(); | ||
})(); |
@@ -17,5 +17,5 @@ var common = require('../common'); | ||
retry.wrap(lib); | ||
assert.equal(lib.fn1.name, 'retryWrapper'); | ||
assert.equal(lib.fn2.name, 'retryWrapper'); | ||
assert.equal(lib.fn3.name, 'retryWrapper'); | ||
assert.equal(lib.fn1.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn2.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn3.name, 'bound retryWrapper'); | ||
}()); | ||
@@ -26,5 +26,5 @@ | ||
retry.wrap(lib, {retries: 2}); | ||
assert.equal(lib.fn1.name, 'retryWrapper'); | ||
assert.equal(lib.fn2.name, 'retryWrapper'); | ||
assert.equal(lib.fn3.name, 'retryWrapper'); | ||
assert.equal(lib.fn1.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn2.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn3.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn1.options.retries, 2); | ||
@@ -38,5 +38,5 @@ assert.equal(lib.fn2.options.retries, 2); | ||
retry.wrap(lib, ['fn2', 'fn3']); | ||
assert.notEqual(lib.fn1.name, 'retryWrapper'); | ||
assert.equal(lib.fn2.name, 'retryWrapper'); | ||
assert.equal(lib.fn3.name, 'retryWrapper'); | ||
assert.notEqual(lib.fn1.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn2.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn3.name, 'bound retryWrapper'); | ||
}()); | ||
@@ -47,5 +47,5 @@ | ||
retry.wrap(lib, {retries: 2}, ['fn2', 'fn3']); | ||
assert.notEqual(lib.fn1.name, 'retryWrapper'); | ||
assert.equal(lib.fn2.name, 'retryWrapper'); | ||
assert.equal(lib.fn3.name, 'retryWrapper'); | ||
assert.notEqual(lib.fn1.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn2.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn3.name, 'bound retryWrapper'); | ||
assert.equal(lib.fn2.options.retries, 2); | ||
@@ -70,2 +70,26 @@ assert.equal(lib.fn3.options.retries, 2); | ||
(function runWrappedSeveralWithoutError() { | ||
var callbacksCalled = 0; | ||
var lib = { | ||
fn1: function (a, callback) { | ||
assert.equal(a, 1); | ||
assert.equal(typeof callback, 'function'); | ||
callback(); | ||
}, | ||
fn2: function (a, callback) { | ||
assert.equal(a, 2); | ||
assert.equal(typeof callback, 'function'); | ||
callback(); | ||
} | ||
}; | ||
retry.wrap(lib, {}, ['fn1', 'fn2']); | ||
lib.fn1(1, function() { | ||
callbacksCalled++; | ||
}); | ||
lib.fn2(2, function() { | ||
callbacksCalled++; | ||
}); | ||
assert.equal(callbacksCalled, 2); | ||
}()); | ||
(function runWrappedWithError() { | ||
@@ -72,0 +96,0 @@ var callbackCalled; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
32210
656
228
3