Relocate statics below constructor
This commit is contained in:
@@ -10,6 +10,31 @@ import { ExponentialBackoffStoppedRetriesError, ExponentialBackoffMaxRetriesHitE
|
|||||||
* The growth rate is the factor by which the delay increases with each attempt.
|
* The growth rate is the factor by which the delay increases with each attempt.
|
||||||
*/
|
*/
|
||||||
export class ExponentialBackoff {
|
export class ExponentialBackoff {
|
||||||
|
private readonly options: ExponentialBackoffOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new exponential-backoff instance.
|
||||||
|
*
|
||||||
|
* Unspecified options use the defaults listed below.
|
||||||
|
*
|
||||||
|
* @param options - Exponential-backoff configuration overrides.
|
||||||
|
* @param options.maxDelay - Maximum delay between retries. Default: `10_000` ms.
|
||||||
|
* @param options.maxAttempts - Maximum number of attempts; `0` retries indefinitely. Default: `10`.
|
||||||
|
* @param options.baseDelay - Delay used as the basis for the first retry. Default: `1_000` ms.
|
||||||
|
* @param options.growthRate - Multiplier applied to the delay after each attempt. Default: `2`.
|
||||||
|
* @param options.jitter - Maximum proportional reduction subtracted from each delay (0–1). Default: `0.1`.
|
||||||
|
*/
|
||||||
|
constructor(options: Partial<ExponentialBackoffOptions> = {}) {
|
||||||
|
this.options = {
|
||||||
|
maxDelay: 10_000,
|
||||||
|
maxAttempts: 10,
|
||||||
|
baseDelay: 1_000,
|
||||||
|
growthRate: 2,
|
||||||
|
jitter: 0.1,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ExponentialBackoff instance
|
* Create a new ExponentialBackoff instance
|
||||||
*
|
*
|
||||||
@@ -43,29 +68,31 @@ export class ExponentialBackoff {
|
|||||||
return backoff.run(taskFn, onError);
|
return backoff.run(taskFn, onError);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly options: ExponentialBackoffOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new exponential-backoff instance.
|
* Calculate the delay before we should attempt to retry
|
||||||
*
|
*
|
||||||
* Unspecified options use the defaults listed below.
|
* @param options - The configuration for the exponential backoff
|
||||||
*
|
* @param attempt - The current attempt number
|
||||||
* @param options - Exponential-backoff configuration overrides.
|
* @returns The time in milliseconds before another attempt should be made
|
||||||
* @param options.maxDelay - Maximum delay between retries. Default: `10_000` ms.
|
|
||||||
* @param options.maxAttempts - Maximum number of attempts; `0` retries indefinitely. Default: `10`.
|
|
||||||
* @param options.baseDelay - Delay used as the basis for the first retry. Default: `1_000` ms.
|
|
||||||
* @param options.growthRate - Multiplier applied to the delay after each attempt. Default: `2`.
|
|
||||||
* @param options.jitter - Maximum proportional reduction subtracted from each delay (0–1). Default: `0.1`.
|
|
||||||
*/
|
*/
|
||||||
constructor(options: Partial<ExponentialBackoffOptions> = {}) {
|
public static calculateDelay(options: ExponentialBackoffOptions, attempt: number): number {
|
||||||
this.options = {
|
// Get the power of the growth rate
|
||||||
maxDelay: 10_000,
|
const power = options.growthRate ** attempt;
|
||||||
maxAttempts: 10,
|
|
||||||
baseDelay: 1_000,
|
// Get the delay before jitter or limit
|
||||||
growthRate: 2,
|
const rawDelay = options.baseDelay * power;
|
||||||
jitter: 0.1,
|
|
||||||
...options,
|
// Cap the delay to the maximum. Do this before the jitter so jitter does not become larger than delay
|
||||||
};
|
const cappedDelay = Math.min(rawDelay, options.maxDelay);
|
||||||
|
|
||||||
|
// Get a random number for the amount to "jitter" the delay by
|
||||||
|
const jitterAmount = Math.random();
|
||||||
|
|
||||||
|
// Calculate the jitter
|
||||||
|
const jitter = jitterAmount * options.jitter * cappedDelay;
|
||||||
|
|
||||||
|
// Subtract the jitter from the delay
|
||||||
|
return cappedDelay - jitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,33 +169,6 @@ export class ExponentialBackoff {
|
|||||||
// We completed the loop without ever succeeding. Throw an ExponentialBackoffMaxRetriesHitError with all the errors we got
|
// We completed the loop without ever succeeding. Throw an ExponentialBackoffMaxRetriesHitError with all the errors we got
|
||||||
throw new ExponentialBackoffMaxRetriesHitError(errors);
|
throw new ExponentialBackoffMaxRetriesHitError(errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the delay before we should attempt to retry
|
|
||||||
*
|
|
||||||
* @param options - The configuration for the exponential backoff
|
|
||||||
* @param attempt - The current attempt number
|
|
||||||
* @returns The time in milliseconds before another attempt should be made
|
|
||||||
*/
|
|
||||||
public static calculateDelay(options: ExponentialBackoffOptions, attempt: number): number {
|
|
||||||
// Get the power of the growth rate
|
|
||||||
const power = options.growthRate ** attempt;
|
|
||||||
|
|
||||||
// Get the delay before jitter or limit
|
|
||||||
const rawDelay = options.baseDelay * power;
|
|
||||||
|
|
||||||
// Cap the delay to the maximum. Do this before the jitter so jitter does not become larger than delay
|
|
||||||
const cappedDelay = Math.min(rawDelay, options.maxDelay);
|
|
||||||
|
|
||||||
// Get a random number for the amount to "jitter" the delay by
|
|
||||||
const jitterAmount = Math.random();
|
|
||||||
|
|
||||||
// Calculate the jitter
|
|
||||||
const jitter = jitterAmount * options.jitter * cappedDelay;
|
|
||||||
|
|
||||||
// Subtract the jitter from the delay
|
|
||||||
return cappedDelay - jitter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ExponentialBackoffOptions = {
|
export type ExponentialBackoffOptions = {
|
||||||
|
|||||||
Reference in New Issue
Block a user