68 lines
1.7 KiB
TypeScript
68 lines
1.7 KiB
TypeScript
|
|
/**
|
||
|
|
* Retry backoff strategies
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type { TBackoffStrategy } from '../webrequest.types.js';
|
||
|
|
|
||
|
|
export interface IBackoffCalculator {
|
||
|
|
calculate(attempt: number, initialDelay: number, maxDelay: number): number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Exponential backoff strategy
|
||
|
|
* Delay increases exponentially: initialDelay * 2^attempt
|
||
|
|
*/
|
||
|
|
export class ExponentialBackoff implements IBackoffCalculator {
|
||
|
|
calculate(attempt: number, initialDelay: number, maxDelay: number): number {
|
||
|
|
const delay = initialDelay * Math.pow(2, attempt - 1);
|
||
|
|
return Math.min(delay, maxDelay);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Linear backoff strategy
|
||
|
|
* Delay increases linearly: initialDelay * attempt
|
||
|
|
*/
|
||
|
|
export class LinearBackoff implements IBackoffCalculator {
|
||
|
|
calculate(attempt: number, initialDelay: number, maxDelay: number): number {
|
||
|
|
const delay = initialDelay * attempt;
|
||
|
|
return Math.min(delay, maxDelay);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Constant backoff strategy
|
||
|
|
* Delay stays constant: initialDelay
|
||
|
|
*/
|
||
|
|
export class ConstantBackoff implements IBackoffCalculator {
|
||
|
|
calculate(attempt: number, initialDelay: number, maxDelay: number): number {
|
||
|
|
return Math.min(initialDelay, maxDelay);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get backoff calculator for a given strategy
|
||
|
|
*/
|
||
|
|
export function getBackoffCalculator(
|
||
|
|
strategy: TBackoffStrategy,
|
||
|
|
): IBackoffCalculator {
|
||
|
|
switch (strategy) {
|
||
|
|
case 'exponential':
|
||
|
|
return new ExponentialBackoff();
|
||
|
|
case 'linear':
|
||
|
|
return new LinearBackoff();
|
||
|
|
case 'constant':
|
||
|
|
return new ConstantBackoff();
|
||
|
|
default:
|
||
|
|
return new ExponentialBackoff();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add jitter to delay to prevent thundering herd
|
||
|
|
*/
|
||
|
|
export function addJitter(delay: number, jitterFactor: number = 0.1): number {
|
||
|
|
const jitter = delay * jitterFactor * Math.random();
|
||
|
|
return delay + jitter;
|
||
|
|
}
|