Skip to content

Commit

Permalink
Rename start/done events to backoff/ready.
Browse files Browse the repository at this point in the history
  • Loading branch information
MathieuTurcotte committed Aug 16, 2012
1 parent ab1b993 commit 8fe294e
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 44 deletions.
54 changes: 27 additions & 27 deletions README.md
Expand Up @@ -17,21 +17,25 @@ var backoff = require('backoff');
The usual way to instantiate a new `Backoff` object is to use one predefined
factory method: `backoff.fibonacci([options])`, `backoff.exponential([options])`.

`Backoff` inherits from `EventEmitter`. One can listen for backoff completion
by listening for `done` events. Registered handlers will be called with the
current backoff number and delay.
`Backoff` inherits from `EventEmitter`. When a backoff starts, a `backoff`
event is emitted and, when a backoff ends, a `ready` event is emitted.
Handlers for these two handlers will always be called with the current backoff
number and delay.

``` js
var fibonacciBackoff = backoff.fibonacci({
randomisationFactor: 0,
initialDelay: 10,
maxDelay: 1000
});

fibonacciBackoff.on('start', function(number, delay) {
fibonacciBackoff.on('backoff', function(number, delay) {
// Do something when backoff starts.
console.log(number + ' ' + delay + 'ms');
});

fibonacciBackoff.on('done', function(number, delay) {
fibonacciBackoff.on('ready', function(number, delay) {
// Do something when backoff ends.
if (number < 15) {
fibonacciBackoff.backoff();
}
Expand Down Expand Up @@ -66,30 +70,26 @@ by calling `reset` after each successful backoff operation.

## API

### backoff.fibonacci([options])

Constructs a Fibonacci backoff (10, 10, 20, 30, 50, etc.).

See bellow for the options description.

### backoff.exponential([options])

Constructs an exponential backoff (10, 20, 40, 80, etc.).

`options` is an object with the following defaults:
The options are:

```js
options = {
randomisationFactor: 0,
initialDelay: 100,
maxDelay: 10000
};
```
- randomisationFactor: defaults to 0, must be between 0 and 1
- initialDelay: defaults to 100 ms
- maxDelay: defaults to 10000 ms

With these values, the backoff delay will increase from 100ms to 10000ms. The
With these values, the backoff delay will increase from 100 ms to 10000 ms. The
randomisation factor controls the range of randomness and must be between 0
and 1. By default, no randomisation is applied on the backoff delay.

### backoff.fibonacci([options])

Constructs a Fibonacci backoff (10, 10, 20, 30, 50, etc.).

The Fibonacci backoff has the same set of options as the exponential backoff.

### Class Backoff

#### new Backoff(strategy)
Expand Down Expand Up @@ -118,20 +118,20 @@ In practice, this method should be called after having successfully completed
the sensitive operation guarded by the backoff instance or if the client code
request to stop any reconnection attempt.

#### Event: 'start'
#### Event: 'backoff'

- number: number of backoffs since last reset
- number: number of backoffs since last reset, starting at 0
- delay: backoff delay in milliseconds

Emitted when a backoff operation is started. Lets the client know how long the
backoff delay will be before the next 'done' event is emitted.
Emitted when a backoff operation is started. Signals to the client how long
the next backoff delay will be.

#### Event: 'done'
#### Event: 'ready'

- number: number of backoffs since last reset
- number: number of backoffs since last reset, starting at 0
- delay: backoff delay in milliseconds

Emitted on backoff completion, effectively signaling that the failing operation
Emitted when a backoff operation is done. Signals that the failing operation
should be retried.

### Interface BackoffStrategy
Expand Down
4 changes: 2 additions & 2 deletions examples/exponential.js
Expand Up @@ -7,11 +7,11 @@ var testBackoff = backoff.exponential({
maxDelay: 1000
});

testBackoff.on('start', function(number, delay) {
testBackoff.on('backoff', function(number, delay) {
console.log('Backoff start: ' + number + ' ' + delay + 'ms');
});

testBackoff.on('done', function(number, delay) {
testBackoff.on('ready', function(number, delay) {
console.log('Backoff done: ' + number + ' ' + delay + 'ms');

if (number < 15) {
Expand Down
4 changes: 2 additions & 2 deletions examples/fibonacci.js
Expand Up @@ -7,11 +7,11 @@ var testBackoff = backoff.fibonacci({
maxDelay: 1000
});

testBackoff.on('start', function(number, delay) {
testBackoff.on('backoff', function(number, delay) {
console.log('Backoff start: ' + number + ' ' + delay + 'ms');
});

testBackoff.on('done', function(number, delay) {
testBackoff.on('ready', function(number, delay) {
console.log('Backoff done: ' + number + ' ' + delay + 'ms');

if (number < 15) {
Expand Down
4 changes: 2 additions & 2 deletions examples/randomized.js
Expand Up @@ -8,11 +8,11 @@ var randomizedBackoff = backoff.fibonacci({
maxDelay: 1000
});

randomizedBackoff.on('start', function(number, delay) {
randomizedBackoff.on('backoff', function(number, delay) {
console.log('Backoff start: ' + number + ' ' + delay + 'ms');
});

randomizedBackoff.on('done', function(number, delay) {
randomizedBackoff.on('ready', function(number, delay) {
console.log('Backoff done: ' + number + ' ' + delay + 'ms');

if (number < 15) {
Expand Down
2 changes: 1 addition & 1 deletion examples/reset.js
Expand Up @@ -4,7 +4,7 @@ var backoff = require('../index');

var backoff = backoff.exponential();

backoff.on('done', function(number, delay) {
backoff.on('ready', function(number, delay) {
console.log('Backoff done: ' + number + ' ' + delay + 'ms');

if (number < 15) {
Expand Down
4 changes: 2 additions & 2 deletions lib/backoff.js
Expand Up @@ -35,7 +35,7 @@ Backoff.prototype.backoff = function() {

this.backoffDelay_ = this.backoffStrategy_.next();
this.timeoutID_ = setTimeout(this.handlers.backoff, this.backoffDelay_);
this.emit('start', this.backoffNumber_, this.backoffDelay_);
this.emit('backoff', this.backoffNumber_, this.backoffDelay_);
};

/**
Expand All @@ -44,7 +44,7 @@ Backoff.prototype.backoff = function() {
*/
Backoff.prototype.onBackoff_ = function() {
this.timeoutID_ = -1;
this.emit('done', this.backoffNumber_++, this.backoffDelay_);
this.emit('ready', this.backoffNumber_++, this.backoffDelay_);
};

/**
Expand Down
41 changes: 33 additions & 8 deletions tests/backoff.js
Expand Up @@ -21,23 +21,23 @@ exports["Backoff"] = {
callback();
},

"a start event should be emitted on backoff start": function(test) {
"the backoff event should be emitted when backoff starts": function(test) {
this.backoffStrategy.next.returns(10);

var spy = new sinon.spy();
this.backoff.on('start', spy);
this.backoff.on('backoff', spy);

this.backoff.backoff();

test.ok(spy.calledOnce);
test.done();
},

"a done event should be emitted on backoff completion": function(test) {
"the ready event should be emitted on backoff completion": function(test) {
this.backoffStrategy.next.returns(10);

var spy = new sinon.spy();
this.backoff.on('done', spy);
this.backoff.on('ready', spy);

this.backoff.backoff();
this.clock.tick(10);
Expand All @@ -46,6 +46,31 @@ exports["Backoff"] = {
test.done();
},

"the backoff event should be passed the backoff delay": function(test) {
this.backoffStrategy.next.returns(989);

var spy = new sinon.spy();
this.backoff.on('backoff', spy);

this.backoff.backoff();

test.equal(spy.getCall(0).args[1], 989);
test.done();
},

"the ready event should be passed the backoff delay": function(test) {
this.backoffStrategy.next.returns(989);

var spy = new sinon.spy();
this.backoff.on('ready', spy);

this.backoff.backoff();
this.clock.tick(989);

test.equal(spy.getCall(0).args[1], 989);
test.done();
},

"calling backoff while a backoff is in progress should throw an error": function(test) {
this.backoffStrategy.next.returns(10);
var backoff = this.backoff;
Expand All @@ -63,18 +88,18 @@ exports["Backoff"] = {
this.backoffStrategy.next.returns(10);

var spy = new sinon.spy();
this.backoff.on('done', spy);
this.backoff.on('ready', spy);

this.backoff.backoff();

this.backoff.reset();
this.clock.tick(100); // 'done' should not be emitted.
this.clock.tick(100); // 'ready' should not be emitted.

test.equals(spy.callCount, 0);
test.done();
},

"reset should reset the backoff delay generator": function(test) {
"reset should reset the backoff strategy": function(test) {
this.backoff.reset();
test.ok(this.backoffStrategy.reset.calledOnce);
test.done();
Expand All @@ -83,7 +108,7 @@ exports["Backoff"] = {
"the backoff number should increase from 0 to N - 1": function(test) {
this.backoffStrategy.next.returns(10);
var spy = new sinon.spy();
this.backoff.on('done', spy);
this.backoff.on('backoff', spy);

for (var i = 0; i < 10; i++) {
this.backoff.backoff();
Expand Down

0 comments on commit 8fe294e

Please sign in to comment.