Skip to content

Instantly share code, notes, and snippets.

@devsnek
Last active June 22, 2017 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devsnek/8b7a4b9e1c38778e30f626575c7eda8d to your computer and use it in GitHub Desktop.
Save devsnek/8b7a4b9e1c38778e30f626575c7eda8d to your computer and use it in GitHub Desktop.
class Backoff {
constructor(min = 500, max, jitter = true) {
this.min = min;
this.max = max !== null ? max : min * 10;
this.jitter = jitter;
this._current = min;
this._timeout = null;
this._fails = 0;
}
get fails() {
return this._fails;
}
get current() {
return this._current;
}
get pending() {
return this._timeout !== null;
}
succeed() {
this.cancel();
this._fails = 0;
this._current = this.min;
}
fail(callback) {
this.fails += 1;
let delay = this._current * 2;
if (this.jitter) delay *= Math.random();
this._current = Math.min(this._current + delay, this.max);
if (callback !== null) {
if (this._timeout !== null) throw new Error('callback already pending');
this._timeout = setTimeout(() => {
try {
if (callback !== null) callback();
} finally {
this._timeout = null;
}
}, this._current);
}
return this._current;
}
cancel() {
if (this._timeout !== null) {
clearTimeout(this._timeout);
this._timeout = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment