Comparing version 0.3.0 to 1.1.0
# Change log | ||
## 1.0.0 | ||
* add retry algorithms | ||
@@ -3,0 +5,0 @@ ## 0.0.1 |
@@ -1,1 +0,7 @@ | ||
module.exports = require('./lib/Stubborn.js'); | ||
module.exports = require('./lib/Stubborn.js'); | ||
module.exports.exponentialBackoff = require('./lib/exponentialBackoff.js'); | ||
module.exports.simpleExponentialBackoff = require('./lib/simpleExponentialBackoff.js'); | ||
module.exports.logarithmicProgression = require('./lib/exponentialBackoff.js'); | ||
module.exports.linear = require('./lib/linear.js'); | ||
module.exports.constant = require('./lib/constant.js'); | ||
module.exports.retryAlgorithm = require('./lib/retryAlgorithm.js') |
var _ = require('lodash'); | ||
var debug = require('debug'); | ||
var events = require('events'); | ||
var onlyOnce = require('only-once'); | ||
var util = require('util'); | ||
var EventEmitter = events.EventEmitter; | ||
var constant = require('./constant') | ||
var EventEmitter = require('events').EventEmitter; | ||
var retryAlgorithm = require('./retryAlgorithm.js'); | ||
util.inherits(Stubborn, EventEmitter); | ||
@@ -24,3 +23,13 @@ | ||
this._delay = _.isUndefined(delay) ? 100 : delay; | ||
this._delayProgression = options.delayProgression; | ||
this._delayProgression = options.delayProgression || options.retryAlgorithm | ||
if (typeof (this._delayProgression) === 'string') { | ||
this._delayProgression = retryAlgorithm(this._delayProgression).apply(null, options.retryAlgorithmArgs || []) | ||
} | ||
if (!this._delayProgression) { | ||
this._delayProgression = constant(1); | ||
} | ||
this._callback = callback; | ||
@@ -74,6 +83,6 @@ this._attempt = 0; | ||
var delay = this._delay; | ||
if (this._delayProgression) { | ||
var factor = this._delayProgression(attempt); | ||
delay = delay * factor; | ||
} | ||
var factor = this._delayProgression(attempt); | ||
delay = delay * factor; | ||
this.emit('schedule', delay, attempt); | ||
@@ -80,0 +89,0 @@ this._setTimeout(this._rerunBound, delay); |
{ | ||
"name": "stubborn", | ||
"version": "0.3.0", | ||
"version": "1.1.0", | ||
"description": "Retry engine", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -44,10 +44,53 @@ ## Stubborn | ||
``` | ||
### pluggable retry algorithm | ||
All retry algorithms are inputed with the current number of attempts, and are required to ouput a number that will be the factor of the delay. | ||
```js | ||
var Stubborn = require('stubborn'); | ||
## Methods | ||
var options = { | ||
maxAttempts: 5, | ||
delay: 1000, | ||
retryAlgorithm: Stubborn.exponentialBackoff() | ||
}; | ||
var stubborn = new Stubborn(task, options, callback); | ||
``` | ||
#### implement your own: | ||
```js | ||
var options = { | ||
maxAttempts: 5, | ||
delay: 1000, | ||
retryAlgorithm: function(attempts) { | ||
// delay next execution in options.delay * attempts * 2 | ||
// thus in attempt #2 we'll have 1000ms * 2 * 2 = 4 seconds delay | ||
return attempts * 2 | ||
} | ||
}; | ||
``` | ||
#### out of the box algorithms: | ||
``` | ||
var Stubborn = require('stubborn'); | ||
var algo1 = Stubborn.exponentialBackoff(2) // classic http://en.wikipedia.org/wiki/Exponential_backoff | ||
var algo2 = Stubborn.simpleExponentialBackoff(2) // same as the above only without the random element | ||
var algo3 = Stubborn.logarithmicProgression(2) // logarithmic progression | ||
var algo4 = Stubborn.linear(1, 0) // ax+b | ||
var algo5 = Stubborm.constant(1) // constant / fixed progression | ||
``` | ||
#### configure using names instead of functions | ||
```js | ||
var options = { | ||
retryAlgorithm: 'linear', | ||
retryAlgorithmArgs: [ 1, 0 ] | ||
} | ||
``` | ||
### Methods | ||
* ```run``` starts specified task, call it only once | ||
* ```cancel``` stops retries | ||
## Events | ||
### Events | ||
* ```run``` | ||
* ```onAttemptError``` | ||
* ```schedule``` |
var _ = require('lodash'); | ||
var chai = require('chai'); | ||
var events = require('events'); | ||
var constant = require('../lib/constant.js') | ||
@@ -8,3 +9,2 @@ var assert = chai.assert; | ||
var EventEmitter = events.EventEmitter; | ||
var Stubborn = require('../lib/Stubborn.js'); | ||
@@ -18,4 +18,3 @@ | ||
maxAttempts: 'testMaxAttempts', | ||
delay: 'testDelay', | ||
delayProgression: 'testDelayProgression' | ||
delay: 'testDelay' | ||
}; | ||
@@ -31,3 +30,3 @@ | ||
assert.strictEqual(stubbon._delay, 'testDelay'); | ||
assert.strictEqual(stubbon._delayProgression, 'testDelayProgression'); | ||
assert.strictEqual(stubbon._delayProgression.name, 'constant'); | ||
assert.strictEqual(stubbon._attempt, 0); | ||
@@ -51,4 +50,4 @@ assert.isFunction(stubbon._rerunBound); | ||
assert.strictEqual(stubbon._maxAttempts, 10); | ||
assert.strictEqual(stubbon._delay, 100); | ||
assert.isUndefined(stubbon._delayProgression); | ||
assert.strictEqual(stubbon._delay, 100); | ||
assert.strictEqual(stubbon._delayProgression.name, 'constant'); | ||
assert.strictEqual(stubbon._attempt, 0); | ||
@@ -60,2 +59,22 @@ assert.isFunction(stubbon._rerunBound); | ||
it('override default retry algorithm by providing a function in the options hash', function() { | ||
var myRetryAlgorithm = function () {} | ||
var testCallback = function() {}; | ||
var stubborn = new Stubborn('testTask', { retryAlgorithm: myRetryAlgorithm }, testCallback); | ||
assert.strictEqual(stubborn._delayProgression, myRetryAlgorithm) | ||
}); | ||
it('override default retry algorithm using a string name of one of the out of box algorithms', function() { | ||
var testCallback = function() {}; | ||
var stubborn = new Stubborn('testTask', { retryAlgorithm: 'linear' }, testCallback); | ||
assert.strictEqual(stubborn._delayProgression.name, 'linear') | ||
}); | ||
it('run throw exception when run already called', function() { | ||
@@ -325,2 +344,4 @@ | ||
_delayProgression: constant(1), | ||
_debug: function() { | ||
@@ -335,3 +356,3 @@ | ||
if (mockEmitCallCount === 1) { | ||
assert.deepEqual(_.toArray(arguments), ['schedule', 'testDelay', 5]); | ||
assert.deepEqual(_.toArray(arguments), ['schedule', 1000, 5]); | ||
} | ||
@@ -345,3 +366,3 @@ mockEmitCallCount++; | ||
_delay: 'testDelay', | ||
_delay: 1000, | ||
@@ -352,3 +373,3 @@ _rerunBound: 'testRerunBound', | ||
assert.strictEqual(callback, 'testRerunBound'); | ||
assert.strictEqual(delay, 'testDelay'); | ||
assert.strictEqual(delay, 1000); | ||
mockSetTimeoutCallCount++; | ||
@@ -355,0 +376,0 @@ } |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
15548
13
392
0
96
1