feat: ensure charging station add op return its station info
[e-mobility-charging-stations-simulator.git] / src / worker / WorkerFixedPool.ts
1 import type { EventEmitterAsyncResource } from 'node:events'
2
3 import { FixedThreadPool, type PoolInfo } from 'poolifier'
4
5 import { WorkerAbstract } from './WorkerAbstract.js'
6 import type { WorkerData, WorkerOptions } from './WorkerTypes.js'
7 import { randomizeDelay, sleep } from './WorkerUtils.js'
8
9 export class WorkerFixedPool<D extends WorkerData, R extends WorkerData> extends WorkerAbstract<
10 D,
11 R
12 > {
13 private readonly pool: FixedThreadPool<D, R>
14
15 /**
16 * Creates a new `WorkerFixedPool`.
17 *
18 * @param workerScript -
19 * @param workerOptions -
20 */
21 constructor (workerScript: string, workerOptions: WorkerOptions) {
22 super(workerScript, workerOptions)
23 this.pool = new FixedThreadPool<D, R>(
24 this.workerOptions.poolMaxSize,
25 this.workerScript,
26 this.workerOptions.poolOptions
27 )
28 }
29
30 get info (): PoolInfo {
31 return this.pool.info
32 }
33
34 get size (): number {
35 return this.pool.info.workerNodes
36 }
37
38 get maxElementsPerWorker (): number | undefined {
39 return undefined
40 }
41
42 get emitter (): EventEmitterAsyncResource | undefined {
43 return this.pool.emitter
44 }
45
46 /** @inheritDoc */
47 public start (): void {
48 this.pool.start()
49 }
50
51 /** @inheritDoc */
52 public async stop (): Promise<void> {
53 await this.pool.destroy()
54 }
55
56 /** @inheritDoc */
57 public async addElement (elementData: D): Promise<R> {
58 const response = await this.pool.execute(elementData)
59 // Start element sequentially to optimize memory at startup
60 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
61 this.workerOptions.elementAddDelay! > 0 &&
62 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
63 (await sleep(randomizeDelay(this.workerOptions.elementAddDelay!)))
64 return response
65 }
66 }