diff --git a/changelog.md b/changelog.md index 9d5c472..04d3577 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # Changelog +## 3.1.3 + +- **fix:** decorrelatedJitter backoff returning NaN after many iterations ([#86](https://github.com/connor4312/cockatiel/issues/86)) + ## 3.1.2 - **chore:** remove test files from dist package ([#84](https://github.com/connor4312/cockatiel/issues/84)) diff --git a/src/backoff/ExponentialBackoffGenerators.test.ts b/src/backoff/ExponentialBackoffGenerators.test.ts index 4de903c..64bfba6 100644 --- a/src/backoff/ExponentialBackoffGenerators.test.ts +++ b/src/backoff/ExponentialBackoffGenerators.test.ts @@ -35,4 +35,21 @@ describe('ExponentialBackoff Generators', () => { } }); } + + it('fixes issue #86', () => { + const options: IExponentialBackoffOptions = { + generator: decorrelatedJitterGenerator, + maxDelay: 15 * 60_000, + exponent: 2, + initialDelay: 45_000, + }; + + let state: any; + for (let k = 1; k < 3000; k++) { + const [delay, nextState] = decorrelatedJitterGenerator(state, options); + expect(delay).to.not.be.NaN; + expect(delay).to.be.gte(0); + state = nextState; + } + }); }); diff --git a/src/backoff/ExponentialBackoffGenerators.ts b/src/backoff/ExponentialBackoffGenerators.ts index 7ffdecf..142c3b2 100644 --- a/src/backoff/ExponentialBackoffGenerators.ts +++ b/src/backoff/ExponentialBackoffGenerators.ts @@ -56,7 +56,7 @@ export const decorrelatedJitterGenerator: GeneratorFn<[number, number]> = (state const [attempt, prev] = state || [0, 0]; const t = attempt + Math.random(); const next = Math.pow(options.exponent, t) * Math.tanh(Math.sqrt(pFactor * t)); - const formulaIntrinsicValue = Math.max(0, next - prev); + const formulaIntrinsicValue = isFinite(next) ? Math.max(0, next - prev) : Infinity; return [ Math.min(formulaIntrinsicValue * rpScalingFactor * options.initialDelay, options.maxDelay), [attempt + 1, next],