refactor: add error name in worker set worker startup error reporting
[e-mobility-charging-stations-simulator.git] / src / charging-station / ChargingStationWorker.ts
1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
2
3 import { AsyncResource } from 'node:async_hooks';
4 import { parentPort } from 'node:worker_threads';
5
6 import { ThreadWorker } from 'poolifier';
7
8 import { ChargingStation } from './ChargingStation';
9 import { BaseError } from '../exception';
10 import type { ChargingStationWorkerData } from '../types';
11 import { Configuration } from '../utils';
12 import { type WorkerData, type WorkerMessage, WorkerMessageEvents } from '../worker';
13
14 const moduleName = 'ChargingStationWorker';
15
16 /**
17 * Creates and starts a charging station instance
18 *
19 * @param data - data sent to worker
20 */
21 const startChargingStation = (data?: ChargingStationWorkerData): void => {
22 new ChargingStation(data!.index, data!.templateFile).start();
23 };
24
25 class ChargingStationWorker<Data extends WorkerData> extends AsyncResource {
26 constructor() {
27 super(moduleName);
28 // Add message listener to create and start charging station from the main thread
29 parentPort?.on('message', (message: WorkerMessage<Data>) => {
30 switch (message.event) {
31 case WorkerMessageEvents.startWorkerElement:
32 try {
33 this.runInAsyncScope(
34 startChargingStation.bind(this) as (data?: Data) => void,
35 this,
36 message.data,
37 );
38 parentPort?.postMessage({
39 event: WorkerMessageEvents.startedWorkerElement,
40 });
41 } catch (error) {
42 parentPort?.postMessage({
43 event: WorkerMessageEvents.startWorkerElementError,
44 data: {
45 name: (error as Error).name,
46 message: (error as Error).message,
47 stack: (error as Error).stack,
48 },
49 });
50 }
51 break;
52 default:
53 throw new BaseError(
54 `Unknown worker event: '${message.event}' received with data: '${JSON.stringify(
55 message.data,
56 undefined,
57 2,
58 )}'`,
59 );
60 }
61 });
62 }
63 }
64
65 export let chargingStationWorker:
66 | ChargingStationWorker<ChargingStationWorkerData>
67 | ThreadWorker<ChargingStationWorkerData>;
68 if (Configuration.workerPoolInUse()) {
69 chargingStationWorker = new ThreadWorker<ChargingStationWorkerData>(startChargingStation);
70 } else {
71 chargingStationWorker = new ChargingStationWorker<ChargingStationWorkerData>();
72 }