93 lines
1.8 KiB
JavaScript
93 lines
1.8 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", {
|
||
|
value: true
|
||
|
});
|
||
|
|
||
|
|
||
|
// copied from discord_app/lib because including from there is broken.
|
||
|
|
||
|
class Backoff {
|
||
|
|
||
|
/**
|
||
|
* Create a backoff instance can automatically backoff retries.
|
||
|
*/
|
||
|
constructor(min = 500, max = null, jitter = true) {
|
||
|
this.min = min;
|
||
|
this.max = max != null ? max : min * 10;
|
||
|
this.jitter = jitter;
|
||
|
|
||
|
this._current = min;
|
||
|
this._timeoutId = null;
|
||
|
this._fails = 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return the number of failures.
|
||
|
*/
|
||
|
get fails() {
|
||
|
return this._fails;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Current backoff value in milliseconds.
|
||
|
*/
|
||
|
get current() {
|
||
|
return this._current;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* A callback is going to fire.
|
||
|
*/
|
||
|
get pending() {
|
||
|
return this._timeoutId != null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clear any pending callbacks and reset the backoff.
|
||
|
*/
|
||
|
succeed() {
|
||
|
this.cancel();
|
||
|
this._fails = 0;
|
||
|
this._current = this.min;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Increment the backoff and schedule a callback if provided.
|
||
|
*/
|
||
|
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._timeoutId != null) {
|
||
|
throw new Error('callback already pending');
|
||
|
}
|
||
|
this._timeoutId = setTimeout(() => {
|
||
|
try {
|
||
|
if (callback != null) {
|
||
|
callback();
|
||
|
}
|
||
|
} finally {
|
||
|
this._timeoutId = null;
|
||
|
}
|
||
|
}, this._current);
|
||
|
}
|
||
|
return this._current;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clear any pending callbacks.
|
||
|
*/
|
||
|
cancel() {
|
||
|
if (this._timeoutId != null) {
|
||
|
clearTimeout(this._timeoutId);
|
||
|
this._timeoutId = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
exports.default = Backoff;
|
||
|
module.exports = exports['default'];
|