@pxtrn/async-backoff
v2.0.2
Published
Backoff failing async calls
Downloads
2
Readme
@pxtrn/async-backoff
Backoff failing async calls until they successfully complete.
Usefull for recoverable errors that most likely go away on retry.
For example errors like ENOTFOUND
, EHOSTUNREACH
etc. on network calls or
EBUSY
on file system calls.
Installation
npm install --save @pxtrn/async-backoff
Usage
Javascript
const { backoff } = require('@pxtrn/async-backoff');
let counter = 1;
async function request() {
console.log(`request number: ${counter}`);
if(counter < 5) {
counter ++;
throw new Error('Some Network error');
}
console.log(`successfully requestd resource`);
return true;
}
(async function() {
try {
const result = await backoff(request, {maxAttempts: 5, retryTimeout: 100});
} catch(err) {
console.error(`Could not request resource`);
}
})();
Typescript
import { backoff } from '@pxtrn/async-backoff';
let counter = 1;
interface IUser {name: string; email: string};
async function request(): Promise<IUser> {
console.log(`request number: ${counter}`);
if(counter < 5) {
counter ++;
throw new Error('Some Network error');
}
console.log(`successfully requestd resource`);
return {name: 'Bob', email: '[email protected]'};
}
(async function() {
try {
const result = await backoff<IUser>(request, {maxAttempts: 5, retryTimeout: 100});
console.log('Got result', result);
} catch(err) {
console.error(`Could not request resource`);
}
})();
Parameters
fn
{async Function} Async function to awaitoptions
{Object}maxAttempts
: {Integer} Max number of function callsretryTimeout
: {Integer} ms to wait. Only for default delayStrategy (return attempts * retryTimeout)retryStrategy
: {Function(err)} return boolean true if another call to fn should be tryed, even maxAttempts has not been reached yetdelayStrategy
: {Function(attempts)} return an integer in ms for which the next attempt should be delayedsignal
: {AbortSignal}
Custom retry strategy
await backoff(request, {
maxAttempts: 5,
retryStrategy: (err) => {
const retryErrors = ['ECONNRESET', 'ENOTFOUND', 'ESOCKETTIMEDOUT'];
return retryErrors.includes(err.code);
}
});
Custom delay strategy
await backoff(request, {
maxAttempts: 5,
delayStrategy: (attempts) => {
return Math.min((Math.pow(2, attempts) * 100), 5e3);
}
});
Aborting a running backoff
Note this does only abort the backoff itself, not the async function passed.
const ac = new AbortController();
setTimeout(() => ac.abort(), 2e3);
await backoff(request, {
signal: ac.signal
});