Make jitter subtract only

This commit is contained in:
2026-07-13 22:07:40 +10:00
parent f346a1fc4f
commit bce4c1552e
2 changed files with 18 additions and 17 deletions

View File

@@ -9,8 +9,8 @@ import { ExponentialBackoffMaxRetriesHitError } from '../source/errors.ts';
const testExponentialBackoffRunUsesDefaultOptions = async (): Promise<void> => {
// Fake timers let us advance time without waiting real seconds between retries.
vi.useFakeTimers();
// Pin Math.random so jitter does not randomize the delay we are about to measure.
vi.spyOn(Math, 'random').mockReturnValue(0.5);
// Pin Math.random to 0 so jitter does not reduce the default delay.
vi.spyOn(Math, 'random').mockReturnValue(0);
try {
// The wrapped function fails on its first invocation and succeeds on the second.
@@ -315,11 +315,11 @@ const testExponentialBackoffCapsDelayAtMaxDelay = async (): Promise<void> => {
};
/**
* Tests that jitter scales the capped delay up or down by jitter * cappedDelay based on Math.random.
* Tests that jitter subtracts up to jitter * cappedDelay from the capped delay based on Math.random.
*/
const testExponentialBackoffAppliesJitter = async (): Promise<void> => {
vi.useFakeTimers();
// random = 1 → jitterDirection = 2*1 - 1 = +1 → full positive 10% jitter on the delay.
// random = 1 → full 10% reduction: 1000 - (1 * 0.1 * 1000) = 900ms.
vi.spyOn(Math, 'random').mockReturnValue(1);
try {
@@ -337,8 +337,11 @@ const testExponentialBackoffAppliesJitter = async (): Promise<void> => {
await Promise.resolve();
expect(fn).toHaveBeenCalledTimes(1);
// cappedDelay = 1000; with +10% jitter the retry fires after 1100ms, not 1000ms.
await vi.advanceTimersByTimeAsync(1_100);
// Advancing 899ms is one ms short of the jittered delay; 900ms triggers the retry.
await vi.advanceTimersByTimeAsync(899);
expect(fn).toHaveBeenCalledTimes(1);
await vi.advanceTimersByTimeAsync(1);
expect(fn).toHaveBeenCalledTimes(2);
await expect(promise).resolves.toBe('success');
@@ -364,7 +367,7 @@ const runTests = async (): Promise<void> => {
test('ExponentialBackoff: retries indefinitely when maxAttempts is 0', testExponentialBackoffRetriesIndefinitelyWhenMaxAttemptsIsZero);
test('ExponentialBackoff: increases delay exponentially between attempts', testExponentialBackoffIncreasesDelayExponentially);
test('ExponentialBackoff: caps delay at maxDelay', testExponentialBackoffCapsDelayAtMaxDelay);
test('ExponentialBackoff: applies jitter around the capped delay', testExponentialBackoffAppliesJitter);
test('ExponentialBackoff: subtracts jitter from the capped delay', testExponentialBackoffAppliesJitter);
};
await runTests();