generated from ryansonshine/typescript-npm-package-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(tryuntilasync, expbackoffasync, expbackoffcalculator): improveme…
…nts to tryUntil Added exponential backoff delay logic for `tryUntilAsync`. Upgraded package version to 6.1.0. This involves updating delay function handling, adding new 'expBackoffAsync' function, and associated unit testing. Also included an updated and more streamlined approach by adding new 'expBackoffCalculator'.
- Loading branch information
Showing
8 changed files
with
292 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { SimpleLogger } from './simpleLogger'; | ||
|
||
interface ExpBackoffAsyncArgs { | ||
/** | ||
* Which iteration this was. | ||
* | ||
* Algorithm is: | ||
* waitTimeMs = startMs * (multiplier ^ iteration) | ||
*/ | ||
iteration: number; | ||
|
||
/** | ||
* Start time for the first iteration. | ||
* | ||
* Defaults to 1000. | ||
* | ||
*/ | ||
startMs?: number; | ||
|
||
/** | ||
* What multiplier is used in the exponential backout wait time. | ||
* | ||
* Defaults to 2. | ||
* | ||
* Algorithm is: | ||
* waitTimeMs = startMs * (multiplier ^ iteration) | ||
*/ | ||
multiplier?: number; | ||
|
||
/** | ||
* A logger to use for logging. | ||
*/ | ||
logger?: SimpleLogger; | ||
} | ||
|
||
interface ExpBackoffAsyncReturn { | ||
timeWaited: number; | ||
} | ||
|
||
|
||
export async function expBackoffAsync( | ||
args: ExpBackoffAsyncArgs | ||
): Promise<ExpBackoffAsyncReturn> { | ||
const { | ||
startMs = 1000, | ||
multiplier = 2, | ||
iteration, | ||
logger | ||
} = args; | ||
|
||
logger?.debug('expBackoffAsync', { startMs, multiplier, iteration }) | ||
|
||
const waitTimeMs = startMs * (multiplier ** iteration); | ||
|
||
logger?.debug('waiting', waitTimeMs) | ||
|
||
return new Promise<ExpBackoffAsyncReturn>((resolve, reject) => { | ||
setTimeout(() => { | ||
logger?.debug('waited', waitTimeMs) | ||
resolve({ | ||
timeWaited: waitTimeMs | ||
}); | ||
}, waitTimeMs); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { SimpleLogger } from './simpleLogger'; | ||
|
||
interface ExponentialBackoffCalculatorArgs { | ||
/** | ||
* Start time for the first iteration. | ||
* | ||
* Defaults to 1000. | ||
* | ||
*/ | ||
startMs?: number; | ||
|
||
/** | ||
* What multiplier is used in the exponential backout wait time. | ||
* | ||
* Defaults to 2. | ||
* | ||
* Algorithm is: | ||
* waitTimeMs = startMs * (multiplier ^ iteration) | ||
*/ | ||
multiplier?: number; | ||
|
||
/** | ||
* Which iteration this was. | ||
* | ||
* Algorithm is: | ||
* waitTimeMs = startMs * (multiplier ^ iteration) | ||
*/ | ||
iteration: number; | ||
|
||
/** | ||
* A logger to use for logging. | ||
*/ | ||
logger?: SimpleLogger; | ||
} | ||
|
||
/** | ||
* Calculates the wait time for exponential backoff. | ||
* | ||
* Returns: `startMs * (multiplier ^ iteration)` | ||
* | ||
* @param args - Arguments for the exponential backoff calculator. | ||
* @returns The wait time in milliseconds. | ||
*/ | ||
export async function createExponentialBackoffCalculator( | ||
args: ExponentialBackoffCalculatorArgs | ||
) { | ||
const { | ||
startMs = 1000, | ||
multiplier = 2, | ||
iteration | ||
} = args; | ||
|
||
return startMs * (multiplier ** iteration); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { expBackoffAsync } from '../src'; | ||
|
||
// Mock timers | ||
jest.useFakeTimers(); | ||
|
||
describe('expBackoffAsync', () => { | ||
// Spy on setTimeout | ||
let setTimeoutSpy: any | ||
|
||
beforeEach(() => { | ||
setTimeoutSpy = jest.spyOn(global, 'setTimeout'); | ||
}); | ||
|
||
afterEach(() => { | ||
setTimeoutSpy.mockRestore(); | ||
}); | ||
|
||
test('should resolve after correct wait time', async () => { | ||
const iteration = 1; | ||
const startMs = 1000; | ||
const multiplier = 2; | ||
const expectedWaitTimeMs = startMs * (multiplier ** iteration); | ||
|
||
// Make sure our spy is set up correctly | ||
expect(setTimeoutSpy).not.toBeCalled(); | ||
|
||
const mockResult = expBackoffAsync({ | ||
iteration, | ||
startMs, | ||
multiplier, | ||
}); | ||
|
||
expect(setTimeoutSpy).toHaveBeenCalledTimes(1); | ||
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), expectedWaitTimeMs); | ||
|
||
jest.advanceTimersByTime(expectedWaitTimeMs); | ||
|
||
await expect(mockResult).resolves.toEqual({ | ||
timeWaited: expectedWaitTimeMs | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters