Nodejs | Thread pool implementations
Tags: node, javascript, opensource, workers
Published: 2020-01-22 23:04:17

# Node Thread Pool :arrow_double_up: :on:

Nodejs introduced worker_threads module to allow a better use of nodejs for CPU intensive tasks, but there is no official thread pool that allow to reuse threads. <br>

So I develop two thread pool on top on worker_threads that you can use with an high level API https://github.com/pioardi/poolifier . <br>

This project contain two thread pool implementations : <br>
The first implementation is a static thread pool , with a defined number of threads that are started at creation time and will be reused.<br>
The second implementation is a dynamic thread pool with a number of threads started at creation time ( these threads will be always active and reused) and other threads created when the load will increase ( with an upper limit, these threads will be reused when active ), the new created threads will be stopped after a configurable period of inactivity. <br>
You have to implement your worker extending the ThreadWorker class<br>

<h2 id="installation">Installation</h2>

```
npm install poolifier --save
```
<h2 id="usage">Usage</h2>

You can implement a worker in a simple way , extending the class ThreadWorker : 

```js
'use strict'
const { ThreadWorker } = require('poolifier')

function yourFunction (data) {
  // this will be executed in the worker thread,
  // the data will be received by using the execute method
  return { ok: 1 }
}

class MyWorker extends ThreadWorker {
  constructor () {
    super(yourFunction, { maxInactiveTime: 1000 * 60})
  }
}
module.exports = new MyWorker()
```

Instantiate your pool based on your needed : 

```js
'use strict'
const { FixedThreadPool, DynamicThreadPool } = require('poolifier')

// a fixed thread pool
const pool = new FixedThreadPool(15,
  './yourWorker.js',
  { errorHandler: (e) => console.error(e), onlineHandler: () => console.log('worker is online') })

// or a dynamic thread pool
const pool = new DynamicThreadPool(10, 100,
  './yourWorker.js',
  { errorHandler: (e) => console.error(e), onlineHandler: () => console.log('worker is online') })

pool.emitter.on('FullPool', () => console.log('Pool is full'))

// the execute method signature is the same for both implementations,
// so you can easy switch from one to another
pool.execute({}).then(res => {
  console.log(res)
}).catch .... 

```
 <h2>Considerations</h2>
Performance is one of the main target of these thread pool implementations, we want to have a strong focus on this.<br>
We already have a bench folder where you can find some comparisons.
To choose your pool consider that with a FixedThreadPool or a DynamicThreadPool ( in this case is important the min parameter passed to the constructor) your application memory footprint will increase . <br>
Increasing the memory footprint, your application will be ready to accept more CPU bound tasks, but during idle time your application will consume more memory. <br>
One good choose from my point of view is to profile your application using Fixed/Dynamic thread pool , and to see your application metrics when you increase/decrease the num of threads. <br>
For example you could keep the memory footprint low choosing a DynamicThreadPool with 5 threads, and allow to create new threads until 50/100 when needed, this is the advantage to use the DynamicThreadPool. <br>
But in general , <strong>always profile your application </strong>

<h2> Contribute </h2>
Pull requests, contributors and feedbacks are welcome , join the project :)