/** | |
* Expose `Backoff`. | |
*/ | |
module.exports = Backoff; | |
/** | |
* Initialize backoff timer with `opts`. | |
* | |
* - `min` initial timeout in milliseconds [100] | |
* - `max` max timeout [10000] | |
* - `jitter` [0] | |
* - `factor` [2] | |
* | |
* @param {Object} opts | |
* @api public | |
*/ | |
function Backoff(opts) { | |
opts = opts || {}; | |
this.ms = opts.min || 100; | |
this.max = opts.max || 10000; | |
this.factor = opts.factor || 2; | |
this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; | |
this.attempts = 0; | |
} | |
/** | |
* Return the backoff duration. | |
* | |
* @return {Number} | |
* @api public | |
*/ | |
Backoff.prototype.duration = function(){ | |
var ms = this.ms * Math.pow(this.factor, this.attempts++); | |
if (this.jitter) { | |
var rand = Math.random(); | |
var deviation = Math.floor(rand * this.jitter * ms); | |
ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; | |
} | |
return Math.min(ms, this.max) | 0; | |
}; | |
/** | |
* Reset the number of attempts. | |
* | |
* @api public | |
*/ | |
Backoff.prototype.reset = function(){ | |
this.attempts = 0; | |
}; | |
/** | |
* Set the minimum duration | |
* | |
* @api public | |
*/ | |
Backoff.prototype.setMin = function(min){ | |
this.ms = min; | |
}; | |
/** | |
* Set the maximum duration | |
* | |
* @api public | |
*/ | |
Backoff.prototype.setMax = function(max){ | |
this.max = max; | |
}; | |
/** | |
* Set the jitter | |
* | |
* @api public | |
*/ | |
Backoff.prototype.setJitter = function(jitter){ | |
this.jitter = jitter; | |
}; | |