1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- // Copyright (c) 2012 Mathieu Turcotte
- // Licensed under the MIT license.
-
- var events = require('events');
- var precond = require('precond');
- var util = require('util');
-
- // A class to hold the state of a backoff operation. Accepts a backoff strategy
- // to generate the backoff delays.
- function Backoff(backoffStrategy) {
- events.EventEmitter.call(this);
-
- this.backoffStrategy_ = backoffStrategy;
- this.maxNumberOfRetry_ = -1;
- this.backoffNumber_ = 0;
- this.backoffDelay_ = 0;
- this.timeoutID_ = -1;
-
- this.handlers = {
- backoff: this.onBackoff_.bind(this)
- };
- }
- util.inherits(Backoff, events.EventEmitter);
-
- // Sets a limit, greater than 0, on the maximum number of backoffs. A 'fail'
- // event will be emitted when the limit is reached.
- Backoff.prototype.failAfter = function(maxNumberOfRetry) {
- precond.checkArgument(maxNumberOfRetry > 0,
- 'Expected a maximum number of retry greater than 0 but got %s.',
- maxNumberOfRetry);
-
- this.maxNumberOfRetry_ = maxNumberOfRetry;
- };
-
- // Starts a backoff operation. Accepts an optional parameter to let the
- // listeners know why the backoff operation was started.
- Backoff.prototype.backoff = function(err) {
- precond.checkState(this.timeoutID_ === -1, 'Backoff in progress.');
-
- if (this.backoffNumber_ === this.maxNumberOfRetry_) {
- this.emit('fail', err);
- this.reset();
- } else {
- this.backoffDelay_ = this.backoffStrategy_.next();
- this.timeoutID_ = setTimeout(this.handlers.backoff, this.backoffDelay_);
- this.emit('backoff', this.backoffNumber_, this.backoffDelay_, err);
- }
- };
-
- // Handles the backoff timeout completion.
- Backoff.prototype.onBackoff_ = function() {
- this.timeoutID_ = -1;
- this.emit('ready', this.backoffNumber_, this.backoffDelay_);
- this.backoffNumber_++;
- };
-
- // Stops any backoff operation and resets the backoff delay to its inital value.
- Backoff.prototype.reset = function() {
- this.backoffNumber_ = 0;
- this.backoffStrategy_.reset();
- clearTimeout(this.timeoutID_);
- this.timeoutID_ = -1;
- };
-
- module.exports = Backoff;
|