Documenation and improvements
[poolifier.git] / lib / workers.js
1 'use strict'
2 const {
3 isMainThread, parentPort
4 } = require('worker_threads')
5 const { AsyncResource } = require('async_hooks')
6
7 /**
8 * An example worker that will be always alive, you just need to extend this class if you want a static pool.<br>
9 * When this worker is inactive for more than 1 minute, it will send this info to the main thread,<br>
10 * if you are using DynamicThreadPool, the workers created after will be killed, the min num of thread will be guaranteed
11 * @author Alessandro Pio Ardizio
12 * @since 0.0.1
13 */
14 class ThreadWorker extends AsyncResource {
15 constructor (fn, opts) {
16 super('worker-thread-pool:pioardi')
17 this.opts = opts || {}
18 this.maxInactiveTime = this.opts.maxInactiveTime || (1000 * 60)
19 this.lastTask = Date.now()
20 if (!fn) throw new Error('Fn parameter is mandatory')
21 // keep the worker active
22 if (!isMainThread) {
23 this.interval = setInterval(this._checkAlive.bind(this), this.maxInactiveTime / 2)
24 this._checkAlive.bind(this)()
25 }
26 parentPort.on('message', (value) => {
27 if (value && value.data && value._id) {
28 // here you will receive messages
29 // console.log('This is the main thread ' + isMainThread)
30 const res = this.runInAsyncScope(fn, null, value.data)
31 this.parent.postMessage({ data: res, _id: value._id })
32 this.lastTask = Date.now()
33 } else if (value.parent) {
34 // save the port to communicate with the main thread
35 // this will be received once
36 this.parent = value.parent
37 } else if (value.kill) {
38 // here is time to kill this thread, just clearing the interval
39 clearInterval(this.interval)
40 this.emitDestroy()
41 }
42 })
43 }
44
45 _checkAlive () {
46 if ((Date.now() - this.lastTask) > this.maxInactiveTime) {
47 this.parent.postMessage({ kill: 1 })
48 }
49 }
50 }
51
52 module.exports.ThreadWorker = ThreadWorker