09b9bedbb60ce90c13fa051b524dfb0d6ff9c41f
1 /* eslint-disable @typescript-eslint/strict-boolean-expressions */
5 FixedThreadPoolOptions
,
6 WorkerWithMessageChannel
9 import { EventEmitter
} from
'events'
11 class MyEmitter
extends EventEmitter
{}
13 export type DynamicThreadPoolOptions
= FixedThreadPoolOptions
16 * A thread pool with a min/max number of threads, is possible to execute tasks in sync or async mode as you prefer.
18 * This thread pool will create new workers when the other ones are busy, until the max number of threads,
19 * when the max number of threads is reached, an event will be emitted, if you want to listen this event use the emitter method.
21 * @author [Alessandro Pio Ardizio](https://github.com/pioardi)
24 export class DynamicThreadPool
<
27 > extends FixedThreadPool
<Data
, Response
> {
28 public readonly emitter
: MyEmitter
31 * @param min Min number of threads that will be always active
32 * @param max Max number of threads that will be active
33 * @param filename A file path with implementation of `ThreadWorker` class, relative path is fine.
34 * @param opts An object with possible options for example `errorHandler`, `onlineHandler`. Default: `{ maxTasks: 1000 }`
37 public readonly min
: number,
38 public readonly max
: number,
39 public readonly filename
: string,
40 public readonly opts
: DynamicThreadPoolOptions
= { maxTasks
: 1000 }
42 super(min
, filename
, opts
)
44 this.emitter
= new MyEmitter()
47 protected chooseWorker (): WorkerWithMessageChannel
{
48 let worker
: WorkerWithMessageChannel
| undefined
49 for (const entry
of this.tasks
) {
57 // a worker is free, use it
60 if (this.workers
.length
=== this.max
) {
61 this.emitter
.emit('FullPool')
62 return super.chooseWorker()
64 // all workers are busy create a new worker
65 const worker
= this.newWorker()
66 worker
.port2
?.on('message', (message
: { kill
?: number }) => {
68 worker
.postMessage({ kill
: 1 })
69 // eslint-disable-next-line no-void
70 void worker
.terminate()
71 // clean workers from data structures
72 const workerIndex
= this.workers
.indexOf(worker
)
73 this.workers
.splice(workerIndex
, 1)
74 this.tasks
.delete(worker
)