77e5e5facd04804f1581d77c2a2e8c568be99b86
[poolifier.git] / lib / dynamic.js
1 'use strict'
2 const FixedThreadPool = require('./fixed')
3 const EventEmitter = require('events')
4 class MyEmitter extends EventEmitter {}
5
6 /**
7 * A thread pool with a min/max number of threads , is possible to execute tasks in sync or async mode as you prefer. <br>
8 * This thread pool will create new workers when the other ones are busy, until the max number of threads,
9 * when the max number of threads is reached, an event will be emitted , if you want to listen this event use the emitter method.
10 * @author Alessandro Pio Ardizio
11 * @since 0.0.1
12 */
13 class DynamicThreadPool extends FixedThreadPool {
14 /**
15 *
16 * @param {Number} min Min number of threads that will be always active
17 * @param {Number} max Max number of threads that will be active
18 */
19 constructor (min, max, filename, opts) {
20 super(min, filename, opts)
21 this.max = max
22 this.emitter = new MyEmitter()
23 }
24
25 _chooseWorker () {
26 let worker
27 for (const entry of this.tasks) {
28 if (entry[1] === 0) {
29 worker = entry[0]
30 break
31 }
32 }
33
34 if (worker) {
35 // a worker is free, use it
36 return worker
37 } else {
38 if (this.workers.length === this.max) {
39 this.emitter.emit('FullPool')
40 return super._chooseWorker()
41 }
42 // all workers are busy create a new worker
43 const worker = this._newWorker()
44 worker.port2.on('message', (message) => {
45 if (message.kill) {
46 worker.postMessage({ kill: 1 })
47 worker.terminate()
48 // clean workers from data structures
49 const myIndex = this.workers.indexOf(worker)
50 this.workers.splice(myIndex, 1)
51 this.tasks.delete(worker)
52 }
53 })
54 return worker
55 }
56 }
57 }
58
59 module.exports = DynamicThreadPool