npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

concurrency-limiter

v0.1.0

Published

Limit the number of asynchronous concurrent tasks running

Downloads

40

Readme

Build Status

concurrency-limiter

Limit the number of asynchronous concurrent tasks running.

Goals

Assume you need to connect to many different WebSocket servers, or retrieve many resources concurrently at the same time. Any asynchronous operation can be started easily with JavaScript, but when too many of them could potentially be executed at the same time it's usually a good idea to limit their number to avoid resource consumption on the browser or the node instance.

Limiting the number of concurrent asynchronous tasks running is the goal of concurrency-limiter.

Getting started

Instantiate a limiter passing the number of allowed concurrent tasks:

const Limiter = require('concurrency-limiter');

const limiter = new Limiter(10);

The limiter created in the code above allows 10 concurrent tasks to be executed together. Awaiting limiter.enter() ensures that subsequent code is only executed when a slot becomes available. The promise returned by enter() is only resolved when less than 10 tasks are running. When a task is complete, the slot can be released by calling limiter.exit(), like in this example:

async function run() {
    await limiter.enter(); // This will "block" until a slot is available.
    await myAsyncTask();
    limiter.exit(); // This releases the slot.
}

The code above ensures that only 10 calls to myAsyncTask() are executed concurrently. Any additional calls will have to wait for a slot to be available. Note that there is no limit to what can be executed between enter() and exit().

It's very important to ensure that, for every enter() call, the corresponding exit() one is also eventually executed, otherwise an acquired slot would never be released. For that reason, the example above should be more correctly written as:

async function run() {
    await limiter.enter();
    try {
        await myAsyncTask();
    } finally {
        limiter.exit();
    }
}

In the simple case a single async function must be executed in limited concurrency, when entering the limiter must be done right before the function is called and exiting right after, limiter.run() can be used instead. The above can be rewritten as:

async function run() {
    await limiter.run(myAsyncTask);
}

The run() method will release the slot even in the case myAsyncTask raises an exception. Also, the awaited result of myAsyncTask is returned.

API reference

Limiter(limit) ⇒ Object

The concurrency limiter.

It is instantiated providing the maximum number of async tasks that are allowed to run concurrently. It has the following methods:

enter() ⇒ Promise

Request a slot for concurrent execution. The returned promise is only resolved when a slot becomes available. The promise is never rejected. This method is usually called before starting an async operation, like:

    await limiter.enter();
    await wsConnect();
    ...
    wsClose();
    limiter.exit();

@returns {Promise} A promise resolved when a slot is available.

exit()

Release a slot for concurrent execution. This method is usually called after an async operation completes.

run(func) ⇒ Promise

Execute the provided async function when a concurrent slot is available, and release the slot when the function completes, returning its result. The limiter is exited even in the case the function raises an exception.

@param {Function} func A function to be awaited when an async slot is available. @returns {Any} The result returned by awaiting the provided function.