[Backoff] Self rewrite

This commit is contained in:
Ducko 2021-12-11 22:10:26 +00:00
parent f10a49b18a
commit 53f389c731

View file

@ -1,94 +1,50 @@
class Backoff { // Heavily based on original for compat module.exports = class Backoff {
/** constructor(min = 500, max = null) {
* Create a backoff instance can automatically backoff retries. this._timeoutId = null; // Setup internal vars
*/ this.fails = 0;
constructor(min = 500, max = null, jitter = true) {
this.min = min; this.min = min; // Setup args
this.max = max != null ? max : min * 10; this.max = max ?? (min * 10);
this.jitter = jitter;
this._current = min; this.current = min;
this._timeoutId = null;
this._fails = 0;
} }
/**
* Return the number of failures.
*/
get pending() { // If timeout currently set / waiting
get fails() { return this._timeoutId !== null;
return this._fails;
} }
/**
* Current backoff value in milliseconds.
*/
succeed() { // Reset state on succeed
this.current = this.min;
this.fails = 0;
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.cancel();
this._fails = 0;
this._current = this.min;
} }
/**
* Increment the backoff and schedule a callback if provided.
*/
fail(callback) { // On fail, wait and callback
const delay = this.current * 2;
fail(callback) { this.current = Math.min(this.current + delay, this.max);
this._fails += 1;
let delay = this._current * 2;
if (this.jitter) { this.fails += 1; // Bump fails
delay *= Math.random();
}
this._current = Math.min(this._current + delay, this.max); if (!callback) return this.current; // No callback given, skip rest of this
if (this._timeoutId !== null) throw new Error('Callback already pending call'); // Timeout already set as waiting for another callback to call, throw error
if (callback != null) { this._timeoutId = setTimeout(() => { // Set new timeout
if (this._timeoutId != null) { try {
throw new Error('callback already pending'); callback(); // Run callback
} finally {
this_timeoutId = null; // Stop tracking timeout internally as it's been executed
} }
}, this.current);
this._timeoutId = setTimeout(() => { return this.current;
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;
}
} }
} cancel() { // Cancel current timeout
if (this._timeoutId === null) return; // If no timeout already, do nothing
module.exports = Backoff; clearTimeout(this._timeoutId); // Stop timeout
this_timeoutId = null; // Stop tracking timeout internally as it's been executed
}
};