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

thread_pools

v2.5.5

Published

Thread pool with Auto-configuration for worker_threads, provides both thread and pool function, has thread-safe storage

Downloads

9

Readme

Thread pool with Auto-configuration for worker_threads, provides both thread and pool function, has thread-safe storage

Usage

Use --experimental-worker flag while running the code.

const Pool = require("thread_pools");

let ezpool = new Pool();
let pool = new Pool({
  threads: 2,
  importGlobal: `const os = require('os');`,
  waitMs: 1000,
});

for (let i = 0; i < 10; i++) {
  pool.threadPool((index) => console.log(os.cpus().length + index), i);
}

pool
  .threadSingle(() => {
    process.env.returnType = "String";
  })
  .then(() => console.log(process.env.returnType));

pool.threadSingleStoppable(() => {}).cancel();

features

  1. Auto configured

  2. Lazy initialize threads in thread pool

  3. can use console.log inside thread function

  4. has thread-safe storage, can pass javascript Object

Notice

  • better initialize Pool only once and Store it in a global variable

  • some libraries are unable to support worker_threads, like bcrypt

  • process.env is thread unsafe, use with caution.

  • thread-safe storage is very expensive

  • func cannot use any pre-declared variable, need to pass in as a parameter

let variable = 10;
pool.threadSingle(() => console.log(variable)); // not gonna work, out of scope
pool.threadSingle((v) => console.log(v), variable); // 10

API

Pool(options)

{
    threads = if No. of cpu < 3, then 2, else (cpu No. * 2 - 2)
    importGlobal : import / require statement for every threads
    waitMs: Main Thread Pool Checker, wait certain time until pools freed up
}

async threadSingle(func, ...param)

func : toStringable / cloneable function, param : parameters of func

single thread runner, very expensive, auto closed.


async threadSingleStoppable(func, ...param)

return {cancel:Function, result:Promise} also auto closed after finish


async threadPool(func, ...param)

func : toStringable / cloneable function, param : parameters of func

use already initialized threads, expensive at the beginning but much faster than threadSingle for larger task


async threadPoolStoppable(func, ...param)

return Promise<{cancel:Function,uid:Number, result:Promise}>

threadPoolStoppable().catch() will not catch the error, use

threadPoolStoppable().then(data=>data.result.catch()) instead

every time you call it, it will generate a unique uid, can use it to call _threadPoolStop

when thread returned a result, it will not be cancelled / terminated, but you can still call it;


async _threadPoolStop(uid = 0)

if(uid > 0) cancel corresponding thread, has no effect on already finished thread

if(uid == 0) delete all threads in thread pool

if(uid < 0) no effect


Inner API

usage

const assist = require("thread_pools").assist;

assist is a keyword, so you have to use this one.

inner api is the function you can use within func

i.e.

threadSingle(() => assist.sleep(2)).then(() => {}); // wait 2 seconds

async assist.sleep(seconds)

resolve after certain seconds


assist.serialize(object)

use eval('('+object+')') to deserialize


async assist.lock()

try to manually acquire the main lock, will wait until the lock is lifted


async assist.unlock()

better call assist.lock() beforehand, other threads may have access to the shared data


async assist.waitComplete(callback)

wait for the return of the event queue (wait until main thread worker's event queue's callback)


async assist.autoLocker(callback)

acquire the lock, call assist.waitComplete, and finally release the lock after callback finshed


async assist.storage(callback = (store = {}) => {})

thread-safe & synced storage, can communicate between different threads, can be used by both single and pool, any change on the store will reflecte on the original pool.storage

pool.storage.p = 0;
pool.threadSingle(() => assist.storage((item) => item.p++)).then(() => console.log(pool.storage));

storage will aquire lock first, then copy main thread storage, wait until user callback finish, update main thread storage, remove lock, and return updated value