You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.3 KiB
JavaScript

'use strict';
var inherits = require('util').inherits;
function Backoff(opts) {
opts = opts || { };
var min = parseInt(opts.min, 10),
max = parseInt(opts.max, 10),
jitter = parseFloat(opts.jitter);
this.min = !isNaN(min) ? min : 10;
this.max = !isNaN(max) ? max: 10*1000;
this.jitter = !isNaN(jitter) && jitter > 0 && jitter <= 1 ? jitter : 0;
this.reset();
}
Backoff.prototype.next = function () {
if (this.jitter) {
var spread = this._spread() * this.jitter;
this.cur += (Math.random() * spread) - (spread / 2);
}
this.cur = Math.max(0, Math.min(this.max, Math.floor(this.cur)));
var cur = this.cur;
this._step();
return cur;
};
Backoff.prototype.reset = function () {
this._reset();
};
function LinearBackoff(opts) {
opts = opts || { };
Backoff.call(this, opts);
var step = parseInt(opts.step, 10);
this.step = !isNaN(step) && step > 0 ? step : 50;
}
inherits(LinearBackoff, Backoff);
LinearBackoff.prototype._spread = function () {
return this.step;
};
LinearBackoff.prototype._step = function () {
this.cur = this.cur + this.step;
};
LinearBackoff.prototype._reset = function () {
this.cur = this.min;
};
function FibonacciBackoff(opts) {
opts = opts || { };
Backoff.call(this, opts);
this.last = 0;
}
inherits(FibonacciBackoff, Backoff);
FibonacciBackoff.prototype._spread = function () {
return (this.cur === this.last) ? this.cur : this.cur - this.last;
};
FibonacciBackoff.prototype._step = function () {
var next = this.last + this.cur;
if (next === 0) { next = 1; }
this.last = this.cur;
this.cur = next;
};
FibonacciBackoff.prototype._reset = function () {
this.cur = this.min;
this.last = 0;
};
function ExponentialBackoff(opts) {
opts = opts || { };
Backoff.call(this, opts);
var factor = parseFloat(opts.factor);
this.factor = !isNaN(factor) && factor > 1 ? factor : 2;
}
inherits(ExponentialBackoff, Backoff);
ExponentialBackoff.prototype._spread = function () {
return this.cur - (this.cur / this.factor);
};
ExponentialBackoff.prototype._step = function () {
if (this.cur === 0) { this.cur = 1; }
else { this.cur *= this.factor; }
};
ExponentialBackoff.prototype._reset = function () {
this.cur = this.min;
};
module.exports = {
Backoff: Backoff,
LinearBackoff: LinearBackoff,
FibonacciBackoff: FibonacciBackoff,
ExponentialBackoff: ExponentialBackoff
};