@sidewinder/async
Advanced tools
+1
-1
| { | ||
| "name": "@sidewinder/async", | ||
| "description": "Sidewinder Async", | ||
| "version": "0.12.12", | ||
| "version": "0.12.14", | ||
| "author": "sinclairzx81", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
+33
-4
| export declare class RetryError extends Error { | ||
| constructor(message: string); | ||
| } | ||
| export type RetryCallback<T> = (attempt: number) => Promise<T>; | ||
| export type RetryCallback<T> = (attempt: number) => Promise<T> | T; | ||
| export interface RetryOptions { | ||
| /** The number of attempts before throwing last error (default is 4) */ | ||
| /** | ||
| * The number of attempts before throwing last error | ||
| * | ||
| * (Default is Infinity) | ||
| */ | ||
| attempts?: number; | ||
| /** The delay between subsequent retry attempts (default is 1000) */ | ||
| /** | ||
| * The millisecond delay between subsequent retry attempts | ||
| * | ||
| * (Default is 1000) | ||
| */ | ||
| delay?: number; | ||
| /** | ||
| * A multiplier used to increase (or decrease) the delay for subsequent retry attempts. | ||
| * This option can be used to implement exponential back-off strategies. | ||
| * | ||
| * (Default is 1.0) | ||
| */ | ||
| multiplier?: number; | ||
| /** | ||
| * This option specifies a upper threshold for multiplied delay values. This option should be | ||
| * set when attempt counts are high and where multipler values are greater than 1.0. | ||
| * | ||
| * (Default is Infinity) | ||
| */ | ||
| maximumDelay?: number; | ||
| /** | ||
| * This option specifies a lower threshold for multiplied delay values. This option should be | ||
| * set when attempt counts are high and where multipler values are less than 1.0. | ||
| * | ||
| * (Default is 0) | ||
| */ | ||
| minimumDelay?: number; | ||
| } | ||
| export declare namespace Retry { | ||
| /** Runs the given callback repeatedly until result `T` can be resolved. Will throw last error if attempts exceed threshold */ | ||
| /** Will repeatedly run the given callback until a value is successfully returned. The function will throw the last callback error if attempts exceed the configured threshold */ | ||
| function run<T>(callback: RetryCallback<T>, options?: RetryOptions): Promise<T>; | ||
| } |
+30
-9
@@ -40,12 +40,30 @@ "use strict"; | ||
| (function (Retry) { | ||
| /** Runs the given callback repeatedly until result `T` can be resolved. Will throw last error if attempts exceed threshold */ | ||
| async function run(callback, options = {}) { | ||
| options.attempts = options.attempts === undefined ? 4 : options.attempts; | ||
| function defaults(options) { | ||
| options.attempts = options.attempts === undefined ? Infinity : options.attempts; | ||
| options.delay = options.delay === undefined ? 1000 : options.delay; | ||
| options.multiplier = options.multiplier === undefined ? 1.0 : options.multiplier; | ||
| options.maximumDelay = options.maximumDelay === undefined ? Infinity : options.maximumDelay; | ||
| options.minimumDelay = options.minimumDelay === undefined ? 0 : options.minimumDelay; | ||
| return options; | ||
| } | ||
| function assert(options) { | ||
| if (options.delay < 0) | ||
| throw new RetryError('Minumum delay is 0'); | ||
| throw new RetryError('Minimum delay is 0'); | ||
| if (options.attempts < 1) | ||
| throw new RetryError(`Minimum retry attempts must be greater than 1`); | ||
| let lastError = null; | ||
| for (let attempt = 0; attempt < options.attempts; attempt++) { | ||
| if (options.multiplier < 0) | ||
| throw new RetryError('Multiplier must be a non-negative number'); | ||
| if (options.maximumDelay < 0) | ||
| throw new RetryError('MaximumDelay must be a non-negative number'); | ||
| if (options.minimumDelay < 0) | ||
| throw new RetryError('MinimumDelay must be a non-negative number'); | ||
| if (options.maximumDelay < options.minimumDelay) | ||
| throw new RetryError('MinimumDelay must be less than MaximumDelay'); | ||
| return options; | ||
| } | ||
| /** Will repeatedly run the given callback until a value is successfully returned. The function will throw the last callback error if attempts exceed the configured threshold */ | ||
| async function run(callback, options = {}) { | ||
| const resolved = assert(defaults(options)); | ||
| let [delay, exception] = [options.delay, null]; | ||
| for (let attempt = 0; attempt < resolved.attempts; attempt++) { | ||
| try { | ||
@@ -55,9 +73,12 @@ return await callback(attempt); | ||
| catch (error) { | ||
| lastError = error; | ||
| await delay_1.Delay.wait(options.delay); | ||
| exception = error; | ||
| await delay_1.Delay.wait(delay); | ||
| delay = delay * resolved.multiplier; | ||
| delay = delay > resolved.maximumDelay ? resolved.maximumDelay : delay; | ||
| delay = delay < resolved.minimumDelay ? resolved.minimumDelay : delay; | ||
| } | ||
| } | ||
| throw lastError; | ||
| throw exception; | ||
| } | ||
| Retry.run = run; | ||
| })(Retry || (exports.Retry = Retry = {})); |
28229
8.21%546
10.08%