| |
| /** |
| * 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; |
| }; |
| |