Exponential backoff generator. This library provide robust retry function.
Install with npm:
npm install exponential-backoff-generator
Requirement:
- Support ECMAScript 2018+
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 countduration
: duration for current attemptssleep
: a function return a promise that will be resolved afterduration
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
]);
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
})
- yoshuawuyts/exponential-backoff: Exponential backoff generator with jitter.
- Designing robust and predictable APIs with idempotency
- segmentio/backo: exponential backoff without the weird cruft
- Exponential backoff - Wikipedia
- Error Retries and Exponential Backoff in AWS - Amazon Web Services
See Releases page.
Install devDependencies and Run npm test
:
npm test
Pull requests and stars are always welcome.
For bugs and feature requests, please create an issue.
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
MIT © azu