1 import type { EventEmitterAsyncResource
} from
'node:events'
3 import { DynamicThreadPool
, type PoolInfo
} from
'poolifier'
5 import { WorkerAbstract
} from
'./WorkerAbstract.js'
6 import type { WorkerData
, WorkerOptions
} from
'./WorkerTypes.js'
7 import { randomizeDelay
, sleep
} from
'./WorkerUtils.js'
9 export class WorkerDynamicPool
<D
extends WorkerData
, R
extends WorkerData
> extends WorkerAbstract
<
13 private readonly pool
: DynamicThreadPool
<D
, R
>
16 * Creates a new `WorkerDynamicPool`.
18 * @param workerScript -
19 * @param workerOptions -
21 constructor (workerScript
: string, workerOptions
: WorkerOptions
) {
22 super(workerScript
, workerOptions
)
23 this.pool
= new DynamicThreadPool
<D
, R
>(
24 this.workerOptions
.poolMinSize
,
25 this.workerOptions
.poolMaxSize
,
27 this.workerOptions
.poolOptions
31 get
info (): PoolInfo
{
36 return this.pool
.info
.workerNodes
39 get
maxElementsPerWorker (): number | undefined {
43 get
emitter (): EventEmitterAsyncResource
| undefined {
44 return this.pool
.emitter
48 public start (): void {
53 public async stop (): Promise
<void> {
54 await this.pool
.destroy()
58 public async addElement (elementData
: D
): Promise
<R
> {
59 const response
= await this.pool
.execute(elementData
)
60 // Start element sequentially to optimize memory at startup
61 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
62 this.workerOptions
.elementAddDelay
! > 0 &&
63 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
64 (await sleep(randomizeDelay(this.workerOptions
.elementAddDelay
!)))