OpenAsar/src/utils/Backoff.js

41 lines
1.2 KiB
JavaScript
Raw Normal View History

module.exports = class Backoff { // Internal library / utility for a class to retry a callback with delays, etc.
2022-02-12 11:17:04 +00:00
constructor(min = 500, max = (min * 10)) {
Object.assign(this, { min, max });
this.reset();
this.pending = () => this._timeoutId != null; // If timeout currently set / waiting
2021-12-09 16:25:14 +00:00
}
2021-12-11 22:10:26 +00:00
fail(callback) { // On fail, wait and callback
2022-02-12 11:17:04 +00:00
this.current = Math.min(this.current + (this.current * 2), this.max);
2021-12-09 16:25:14 +00:00
2022-02-12 11:17:04 +00:00
this.fails++; // Bump fails
2021-12-09 16:25:14 +00:00
2021-12-11 22:10:26 +00:00
if (!callback) return this.current; // No callback given, skip rest of this
2022-02-12 11:17:04 +00:00
if (this._timeoutId != null) throw new Error(); // Timeout already set as waiting for another callback to call, throw error
2021-12-09 16:25:14 +00:00
2021-12-11 22:10:26 +00:00
this._timeoutId = setTimeout(() => { // Set new timeout
try {
callback(); // Run callback
} finally {
2022-01-21 12:39:00 +00:00
this._timeoutId = null; // Stop tracking timeout internally as it's been executed
2021-12-09 16:25:14 +00:00
}
2021-12-11 22:10:26 +00:00
}, this.current);
2021-12-09 16:25:14 +00:00
2021-12-11 22:10:26 +00:00
return this.current;
2021-12-09 16:25:14 +00:00
}
2022-02-12 11:17:04 +00:00
succeed() { // Reset and cancel
this.reset();
this.cancel();
}
2021-12-11 22:10:26 +00:00
cancel() { // Cancel current timeout
2022-02-12 11:17:04 +00:00
this._timeoutId = clearTimeout(this._timeoutId); // Stop timeout
}
2021-12-09 16:25:14 +00:00
2022-02-12 11:17:04 +00:00
reset() { // Reset internal state
this.current = this.min;
this.fails = 0;
2021-12-09 16:25:14 +00:00
}
2021-12-11 22:10:26 +00:00
};