UNPKG

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
"use strict"; 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;