Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-worker-threads-pool

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-worker-threads-pool - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

src/dynamic-pool.js

134

index.js

@@ -1,132 +0,4 @@

const { Worker } = require('worker_threads');
/**
* worker in the pool.
*/
class PoolWorker extends Worker {
/**
* @param { Pool } pool pool that own this worker
*/
constructor(pool) {
super(pool.filePath);
this.pool = pool;
// working status.
this.isFree = true;
// call done method when work finished.
this.prependListener('message', () => this.done());
this.once('exit', code => {
if (this.pool.isDeprecated || code === 0) {
// exit normally, do nothing.
return;
}
// exit with exception.
this.handleException();
});
}
/**
* start working.
* @param {*} param
*/
work(param) {
this.isFree = false;
this.postMessage(param);
}
/**
* work finished.
*/
done() {
this.isFree = true;
}
/**
* request pool to replace this
* broken worker with a new one.
*/
handleException() {
this.pool._replace(this);
}
}
/**
* "waiting" for the next event loop.
*/
function nextLoop() {
return new Promise((resolve, _) => {
setTimeout(resolve, 20);
});
}
/**
* threads pool with node's worker_threads.
*/
module.exports = class Pool {
/**
* @param { String } filePath absolute path of the worker script.
* @param { Number } num number of workers.
*/
constructor(filePath, num) {
if (typeof filePath !== 'string') {
throw new Error('"filename" must be the type of string!');
}
if (typeof num !== 'number') {
throw new Error('"max" must be the type of number!');
}
if (Number.isNaN(num)) {
throw new Error('"max" must not be NaN!');
}
if (num < 1) {
throw new Error('"max" must not be lower than 1!');
}
// path of the script this pool will use.
this.filePath = filePath;
// pool status.
this.isDeprecated = false;
// worker list.
this.workers = Array.from(new Array(num), _ => new PoolWorker(this));
}
/**
* choose a worker to do this task.
* @param {*} param
*/
async exec(param) {
const worker = this.workers.find(worker => worker.isFree);
if (!worker) {
// pool is busy, "waiting" for the next event loop.
await nextLoop();
return this.exec(param);
}
return new Promise((resolve, reject) => {
worker.once('message', resolve);
worker.once('error', reject);
worker.work(param);
});
}
/**
* replace this broken worker with a new one.
* @param { PoolWorker } worker
*/
_replace(worker) {
const index = this.workers.indexOf(worker);
if (index !== -1) {
this.workers[index] = new PoolWorker(this);
// console.log('--------------------- Replaced --------------------');
}
}
/**
* terminate all workers in this pool.
*/
destroy() {
this.isDeprecated = true;
this.workers.forEach(worker => worker.terminate());
this.workers = null;
}
module.exports = {
StaticPool: require('./src/static-pool'),
DynamicPool: require('./src/dynamic-pool')
}
{
"name": "node-worker-threads-pool",
"version": "1.0.0",
"version": "1.0.1",
"description": "simple worker pool using node's worker_threads api.",

@@ -10,3 +10,5 @@ "main": "index.js",

"scripts": {
"example": "node --experimental-worker ./example"
"static-function": "node --experimental-worker ./example/static-with-function",
"static-file": "node --experimental-worker ./example/static-with-worker-file",
"dynamic": "node --experimental-worker ./example/dynamic"
},

@@ -25,7 +27,8 @@ "repository": {

"author": "mokuo",
"license": "GPL-3.0",
"license": "MIT",
"bugs": {
"url": "https://github.com/SUCHMOKUO/node-worker-threads-pool/issues"
},
"homepage": "https://github.com/SUCHMOKUO/node-worker-threads-pool#readme"
"homepage": "https://github.com/SUCHMOKUO/node-worker-threads-pool#readme",
"dependencies": {}
}
# node-worker-threads-pool
[![](https://img.shields.io/npm/v/node-worker-threads-pool.svg)](https://www.npmjs.com/package/node-worker-threads-pool)
![](https://img.shields.io/badge/dependencies-none-brightgreen.svg)
![](https://img.shields.io/npm/dt/node-worker-threads-pool.svg)
![](https://img.shields.io/npm/l/node-worker-threads-pool.svg)
Simple worker threads pool using Node's worker_threads module.

@@ -7,3 +13,3 @@

1. This module can only run in Node.js.
2. Since Node's worker_threads module is still in stage of **Experimental**, this module can be accessed only if the --experimental-worker flag is added.
2. Since Node's worker_threads module is still in stage of **Experimental**, this module can be accessed ~~only if the `--experimental-worker` flag is added.~~, if node.js version is above 11.7.0, worker api is exposed by default.

@@ -16,7 +22,30 @@ ## Installation

## Example
## API
## `Class: StaticPool`
Instance of StaticPool is a threads pool with static task provided.
### `new StaticPool(opt)`
- `opt`
- `size` `<number>` Number of workers in this pool.
- `task` `<string | function>` Static task to do. It can be a absolute path of worker file or a function. **Notice: If task is a function, you can not use closure in it! If you do want to use external data in the function, you can use workerData to pass some [cloneable data](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm).**
- `workerData` `<any>` [Cloneable data](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) you want to access in task function. eg. use `workerData[property]` in task function to access the data you passed.
### `staticPool.exec(param)`
- `param` - The param your worker script or task function need.
- Returns: `<Promise>`
Choose one idle worker in the pool to execute your heavy task with the param you provided. The Promise is resolved with the result.
### `staticPool.destroy()`
Call `worker.terminate()` for every worker in the pool and release them.
### Example (with worker file)
### Run the example
```
npm run example
npm run static-file
```

@@ -52,8 +81,11 @@

```js
const Pool = require('node-worker-threads-pool');
const { StaticPool } = require('node-worker-threads-pool');
const filePath = 'absolute/path/to/your/worker/script';
const num = 4; // The number of workers in this pool.
const pool = new Pool(filePath, num);
const pool = new StaticPool({
size: 4,
task: filePath
});
for (let i = 0; i < 20; i++) {

@@ -73,22 +105,101 @@ (async () => {

## API
### Example (with task function)
### `new Pool(filePath, num)`
### Run the example
```
npm run static-function
```
- `filePath` - The absolute path of your worker.js file.
- `num` - The number of the workers in your pool.
### In the main.js :
```js
const { StaticPool } = require('node-worker-threads-pool');
### `pool.exec(data)`
const pool = new StaticPool({
size: 4,
task: function(n) {
const num = workerData.num;
for (let i = 0; i < num; i++) {
n += i;
}
return n;
},
workerData: {
num: 1 << 30
}
});
- `data` - The data your worker script need.
for (let i = 0; i < 20; i++) {
(async () => {
const res = await pool.exec(i);
console.log(`result${i}:`, res);
})();
}
```
## `Class: DynamicPool`
Instance of DynamicPool is a threads pool executes dynamic task function provided every call.
### `new DynamicPool(size)`
- `size` `<number>` Number of workers in this pool.
### `dynamicPool.exec(opt)`
- `opt`
- `task` `<function>` Function as a task to do. **Notice: You can not use closure in task function! If you do want to use external data in the function, you can use workerData to pass some [cloneable data](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm).**
- `workerData` `<any>` [Cloneable data](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) you want to access in task function. eg. use `workerData[property]` in task function to access the data you passed.
- Returns: `<Promise>`
Choose one idle worker in the pool to execute your heavy task with the data you provided. The Promise is resolved with the result your worker generated.
Choose one idle worker in the pool to execute your task function. The Promise is resolved with the result your task returned.
### `pool.destroy()`
### `dynamicPool.destroy()`
Call `worker.terminate()` for every worker in the pool and release them.
## License
### Example
node-worker-threads-pool is licensed under the GNU General Public License v3 (GPL-3) (http://www.gnu.org/copyleft/gpl.html).
### Run the example
```
npm run dynamic
```
### In the main.js :
```js
const { DynamicPool } = require('node-worker-threads-pool');
const pool = new DynamicPool(4);
function task1() {
// something heavy.
}
function task2() {
// something heavy too.
}
// execute task1
(async () => {
const res = await pool.exec({
task: task1,
workerData: {
... // some data
}
});
console.log(res);
})();
// execute task2
(async () => {
const res = await pool.exec({
task: task2,
workerData: {
... // some data
}
});
console.log(res);
})();
```

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc