Add ClearChargingProfile OCPP command support.
[e-mobility-charging-stations-simulator.git] / src / worker / WorkerSet.ts
CommitLineData
c045d9a9
JB
1import { WorkerData, WorkerEvents, WorkerSetElement } from '../types/Worker';
2
6013bc53
JB
3import Constants from '../utils/Constants';
4import Utils from '../utils/Utils';
5import { Worker } from 'worker_threads';
144cabe0 6import Wrk from './Wrk';
6013bc53
JB
7
8export default class WorkerSet extends Wrk {
9 public maxElementsPerWorker: number;
c045d9a9 10 private workers: Set<WorkerSetElement>;
6013bc53
JB
11
12 /**
13 * Create a new `WorkerSet`.
14 *
15 * @param {string} workerScript
16 * @param {number} maxElementsPerWorker
17 */
18 constructor(workerScript: string, maxElementsPerWorker = 1) {
19 super(workerScript);
c045d9a9 20 this.workers = new Set<WorkerSetElement>();
6013bc53 21 this.maxElementsPerWorker = maxElementsPerWorker;
6013bc53
JB
22 }
23
24 get size(): number {
25 return this.workers.size;
26 }
27
28 /**
29 *
30 * @return {Promise<void>}
31 * @public
32 */
33 public async addElement(elementData: WorkerData): Promise<void> {
34 if (!this.workers) {
35 throw Error('Cannot add a WorkerSet element: workers set does not exist');
36 }
c045d9a9 37 if (this.getLastWorkerSetElement().numberOfWorkerElements >= this.maxElementsPerWorker) {
6013bc53 38 void this.startWorker();
6013bc53
JB
39 // Start worker sequentially to optimize memory at startup
40 void Utils.sleep(Constants.START_WORKER_DELAY);
41 }
3e1416d8 42 this.getLastWorker().postMessage({ id: WorkerEvents.START_WORKER_ELEMENT, workerData: elementData });
c045d9a9 43 this.getLastWorkerSetElement().numberOfWorkerElements++;
6013bc53
JB
44 }
45
46 /**
47 *
48 * @return {Promise<void>}
49 * @public
50 */
51 public async start(): Promise<void> {
52 await this.startWorker();
53 // Start worker sequentially to optimize memory at startup
54 await Utils.sleep(Constants.START_WORKER_DELAY);
55 }
56
57 /**
58 *
59 * @return {Promise}
60 * @private
61 */
62 private async startWorker() {
63 return new Promise((resolve, reject) => {
64 const worker = new Worker(this.workerScript);
65 worker.on('message', resolve);
66 worker.on('error', reject);
67 worker.on('exit', (code) => {
68 if (code !== 0) {
69 reject(new Error(`Worker stopped with exit code ${code}`));
70 }
71 });
c045d9a9 72 this.workers.add({ worker, numberOfWorkerElements: 0 });
6013bc53
JB
73 });
74 }
75
c045d9a9
JB
76 private getLastWorkerSetElement(): WorkerSetElement {
77 let workerSetElement: WorkerSetElement;
6013bc53 78 // eslint-disable-next-line no-empty
c045d9a9
JB
79 for (workerSetElement of this.workers) { }
80 return workerSetElement;
81 }
82
83 private getLastWorker(): Worker {
84 return this.getLastWorkerSetElement().worker;
6013bc53
JB
85 }
86}