GithubHelp home page GithubHelp logo

regevbr / busywait.js Goto Github PK

View Code? Open in Web Editor NEW
10.0 3.0 1.0 212 KB

Simple Async busy wait module for Node.JS

License: GNU General Public License v2.0

TypeScript 100.00%
nodejs node promise promises javascript npm npm-package npm-module javascript-library loop

busywait.js's Introduction

Npm Version node Build status Test Coverage Maintainability Known Vulnerabilities

busywait.js

Simple Async busy wait module for Node.JS

Main features

  • Simple api to busy wait for a desired outcome
  • Exponential backoff (with optional full jitter) support
  • Slim library (single file, 100 lines of code, no dependencies)
  • Full typescript support

Quick example

import {busywait} from 'busywait';

const waitUntil = Date.now() + 2500;

const checkFn = async (iteration: number, delay: number, totalDelay: number): Promise<string> => {
    console.log(`Running iteration ${iteration} after delay of ${delay}ms and total delay of ${totalDelay}`);
    if (Date.now() > waitUntil) {
        return `success`;
    }
    throw new Error('custom error');
};

(async () => {
    const result = await busywait(checkFn, {
        sleepTime: 500,
        maxChecks: 20,
    })
    console.log(`Finished after ${result.backoff.time}ms (${result.backoff.iterations} iterations) with result ${result.result}`);
})();

Will result in:

Running iteration 1 after delay of 0ms and total delay of 1
Running iteration 2 after delay of 500ms and total delay of 504
Running iteration 3 after delay of 500ms and total delay of 1007
Running iteration 4 after delay of 500ms and total delay of 1508
Running iteration 5 after delay of 500ms and total delay of 2010
Running iteration 6 after delay of 500ms and total delay of 2511
Finished after 2511ms (6 iterations) with result success

Exponential backoff

import {busywait} from 'busywait';

const waitUntil = Date.now() + 2500;

const checkFn = async (iteration: number, delay: number, totalDelay: number): Promise<string> => {
    console.log(`Running iteration ${iteration} after delay of ${delay}ms and total delay of ${totalDelay}`);
    if (Date.now() > waitUntil) {
        return `success`;
    }
    throw new Error('custom error');
};

(async () => {
    const result = await busywait(checkFn, {
        sleepTime: 100,
        jitter: 'none',
        multiplier: 2,
    })
    console.log(`Finished after ${result.backoff.time}ms (${result.backoff.iterations} iterations) with result ${result.result}`);
})();

Will result in:

Running iteration 1 after delay of 0ms and total delay of 1
Running iteration 2 after delay of 100ms and total delay of 104
Running iteration 3 after delay of 200ms and total delay of 306
Running iteration 4 after delay of 400ms and total delay of 707
Running iteration 5 after delay of 800ms and total delay of 1509
Running iteration 6 after delay of 1600ms and total delay of 3110
Finished after 3110ms (6 iterations) with result success

Exponential backoff with full jitter

import {busywait} from 'busywait';

const waitUntil = Date.now() + 2500;

const checkFn = async (iteration: number, delay: number, totalDelay: number): Promise<string> => {
    console.log(`Running iteration ${iteration} after delay of ${delay}ms and total delay of ${totalDelay}`);
    if (Date.now() > waitUntil) {
        return `success`;
    }
    throw new Error('custom error');
};

(async () => {
    const result = await busywait(checkFn, {
        sleepTime: 100,
        jitter: 'full',
        multiplier: 2,
        waitFirst: true,
    })
    console.log(`Finished after ${result.backoff.time}ms (${result.backoff.iterations} iterations) with result ${result.result}`);
})();

Will result in:

Running iteration 1 after delay of 31ms and total delay of 31
Running iteration 2 after delay of 165ms and total delay of 199
Running iteration 3 after delay of 217ms and total delay of 417
Running iteration 4 after delay of 378ms and total delay of 796
Running iteration 5 after delay of 1397ms and total delay of 2195
Running iteration 6 after delay of 1656ms and total delay of 3853
Finished after 3853ms (6 iterations) with result success

Install

npm install busywait

Parameters

checkFn

A function that takes a single optional argument, which is the current iteration number.

Args
  • iteration - The current iteration number (starting from 1)
  • delay - The last delay (in ms) that was applied
  • totalDelay - The total delay (in ms) applied so far
Return

Either:

  • a non promised value (in which case, a failed check should throw an error)
  • a promised value (in which case, a failed check should return a rejected promise)

options

mandatory
  • sleepTime - Time in ms to wait between checks. In the exponential mode, will be the base sleep time.
optional
  • multiplier - The exponential multiplier. Set to 2 or higher to achieve exponential backoff (default: 1 - i.e. linear backoff)
  • maxDelay - The max delay value between checks in ms (default: infinity)
  • maxChecks - The max number of checks to perform before failing (default: infinity)
  • waitFirst - Should we wait the sleepTime before performing the first check (default: false)
  • jitter - ('none' | 'full') The jitter mode to use (default: none)
  • failMsg - Custom error message to reject the promise with

Return value

Return value is a promise.

  • The promise will be resolved if the checkFn was resolved within a legal number of checks.
  • The promise will be rejected if the checkFn rejected (or threw an error) maxChecks times.

Promise resolved value:

  • backoff.iterations - The number of iterations it took to finish
  • backoff.time - The number of time it took to finish
  • result - The resolved value of checkFn

Contributing

All contributions are happily welcomed!
Please make all pull requests to the master branch from your fork and ensure tests pass locally.

busywait.js's People

Contributors

regevbr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

lchayoun

busywait.js's Issues

add optional skip of first check

Currently first check is performed without waiting (actually waiting one tick).
Should add option to skip it and make it wait in the beginning for the sleepTime

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.