Skip to content

Exponential backoff generator. Provide robust retry function.

License

Notifications You must be signed in to change notification settings

azu/exponential-backoff-generator

Repository files navigation

exponential-backoff-generator Actions Status: test

Exponential backoff generator. This library provide robust retry function.

Install

Install with npm:

npm install exponential-backoff-generator

Requirement:

  • Support ECMAScript 2018+

Usage

export type BackoffOptions = {
    // max retry count
    // Default: 7
    retries?: number;
    // Initial timeout in milliseconds
    // Default: 100
    // Note: `min` should be grater than 0.
    min?: number;
    // max timeout in milliseconds
    // Default: 10 * 1000(10 seconds)
    max?: number;
    // Timeout will be multiplied by Factor.
    // Default: 2
    // Default durations are 2 * 100, 4 * 100, 8 * 100, 16 * 100, 32 * 100
    factor?: number;
    // Adding random jitter to each duration
    // jitter value should be 0 - 1.0
    // jitter value is seed value for Math.random().
    // Default: 0
    // For more details, see https://aws.amazon.com/jp/blogs/architecture/exponential-backoff-and-jitter/
    jitter?: number;
}
export declare function generateBackoff(options?: BackoffOptions): IterableIterator<{
    attempts: number;
    duration: number;
    sleep(): Promise<{}>;
}>;

generateBackoff() function return an iterable objects. The iterable objects has these properties.

  • attempts: current try count
  • duration: duration for current attempts
  • sleep: a function return a promise that will be resolved after duration

It works with for...of statement.

import { generateBackoff } from "exponential-backoff-generator";
const doAsyncTask = async () => {
    const backoff = generateBackoff();
    for (const { sleep } of backoff) {
        try {
            return await YourAsyncTaskWantToRetry();
        } catch(error) {
            await sleep(); // wait 100ms, 200ms, 400ms, 800ms ...
        }
    }
    throw new Error("YourAsyncTaskWantToRetry failed at all");
};

doAsyncTask().then(result => {
    console.log(result); // YourAsyncTaskWantToRetry resolved value
}).catch(error => {
    console.error(error); // Error: YourAsyncTaskWantToRetry failed at all
});

Array.from() create an array from iterable object.

import { generateBackoff } from "exponential-backoff-generator";
const backoff = generateBackoff();
// create duration array from iterable objects.
const generated = Array.from(backoff, (({ duration }) => duration));
assert.deepStrictEqual(generated, [
    100, // duration for each attempt
    200,
    400,
    800,
    1600,
    3200,
    6400,
    10000
]);

Examples

const doAsyncTask = async () => {
    const rejectOrResolve = () => {
        if (Math.random() < 0.5) {
            return Promise.resolve("value");
        } else {
            return Promise.reject(new Error("reject"));
        }
    };
    const backoff = generateBackoff({
        retries: 7, // max retry count
        min: 100, // min duration is 100ms
        max: 10 * 1000 // max duration is 10sec
    });
    for (const { sleep } of backoff) {
        try {
            // Do not forget `await`!
            return await rejectOrResolve();
        } catch(error) {
            await sleep();
        }
    }
    // all retries are failed, invoke current line
    throw new Error("doAsyncTask failed at all");
};

doAsyncTask().then(value => {
    // if anyone retry is success, call then block
    console.log(value); // => "value"
}).catch(error => {
    // if all retries are failed, call catch block
    console.error(error); // => Error: doAsyncTask failed at all
})

See Also

Changelog

See Releases page.

Running tests

Install devDependencies and Run npm test:

npm test

Contributing

Pull requests and stars are always welcome.

For bugs and feature requests, please create an issue.

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

Author

License

MIT © azu