dash-core
Version:
A foundational toolkit of types, collections, services, and architectural patterns designed to accelerate application development.
64 lines (63 loc) • 2.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExponentialBackoff = void 0;
const dash_core_1 = require("dash-core");
/**
* Implements exponential backoff with optional jitter for retrying operations.
*/
class ExponentialBackoff {
options;
/**
* Creates an instance of the ExponentialBackoff class with the specified options.
* @param {ExponentialBackoffOptions} options - Configuration options for the backoff mechanism.
* @param {TimeSpan} options.initialDelay - The initial delay before the first retry attempt.
* @param {TimeSpan} options.maxDelay - The maximum delay allowed between retries.
* @param {number} options.factor - The factor by which the delay increases after each failure.
* @param {TimeSpan} [options.jitter] - An optional jitter value that is added randomly to the delay (optional).
*/
constructor(options) {
this.options = options;
}
/**
* Executes the given operation and applies exponential backoff with retries.
* The operation will be retried until it succeeds or the maximum delay is reached.
* @param {() => Promise<TResult>} operation - The asynchronous operation to execute and retry in case of failure.
* @returns {Promise<TResult>} A promise that resolves with the result of the operation if it succeeds, or rejects with the last error if all attempts fail.
*/
execute(operation) {
return new Promise(async (resolve, reject) => {
let lastError = null;
let currentDelay = this.options.initialDelay;
while (currentDelay <= this.options.maxDelay) {
try {
const result = await this.attempt(operation);
resolve(result);
return;
}
catch (error) {
lastError = error;
await (0, dash_core_1.Wait)(currentDelay);
currentDelay = this.getUpdatedDelay(currentDelay);
}
}
reject(lastError);
});
}
attempt(operation) {
return new Promise(async (resolve, reject) => {
try {
const result = await operation();
resolve(result);
}
catch (error) {
reject(error);
}
});
}
getUpdatedDelay(currentDelay) {
const jitter = this.options.jitter ? Math.random() * this.options.jitter.totalMilliseconds : 0;
const newDelay = (currentDelay.totalMilliseconds * this.options.factor) + jitter;
return dash_core_1.TimeSpan.fromMilliseconds(newDelay);
}
}
exports.ExponentialBackoff = ExponentialBackoff;