X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FBootstrap.ts;h=ca45d287e139407ca66858f11c94dcbb3fc23d3c;hb=44eb6026079c8dc2c77b10a96a42d0c0b2da7c8f;hp=85f8f371cf64ade08d7e40bd688cd972970a527e;hpb=8a36b1eb6df21e7ff434b36333d26739edf0e146;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/Bootstrap.ts b/src/charging-station/Bootstrap.ts index 85f8f371..ca45d287 100644 --- a/src/charging-station/Bootstrap.ts +++ b/src/charging-station/Bootstrap.ts @@ -1,37 +1,40 @@ -// Partial Copyright Jerome Benoit. 2021. All Rights Reserved. +// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved. import path from 'path'; import { fileURLToPath } from 'url'; -import { isMainThread } from 'worker_threads'; +import { type Worker, isMainThread } from 'worker_threads'; import chalk from 'chalk'; +import { ChargingStationUtils } from './ChargingStationUtils'; +import type { AbstractUIServer } from './ui-server/AbstractUIServer'; +import UIServerFactory from './ui-server/UIServerFactory'; import { version } from '../../package.json'; import BaseError from '../exception/BaseError'; import type { Storage } from '../performance/storage/Storage'; import { StorageFactory } from '../performance/storage/StorageFactory'; import { - ChargingStationData, - ChargingStationWorkerData, - ChargingStationWorkerMessage, - ChargingStationWorkerMessageData, + type ChargingStationData, + type ChargingStationWorkerData, + type ChargingStationWorkerMessage, + type ChargingStationWorkerMessageData, ChargingStationWorkerMessageEvents, } from '../types/ChargingStationWorker'; import type { StationTemplateUrl } from '../types/ConfigurationData'; import type { Statistics } from '../types/Statistics'; +import type { MessageHandler } from '../types/Worker'; import Configuration from '../utils/Configuration'; import logger from '../utils/Logger'; import Utils from '../utils/Utils'; import type WorkerAbstract from '../worker/WorkerAbstract'; import WorkerFactory from '../worker/WorkerFactory'; -import { ChargingStationUtils } from './ChargingStationUtils'; -import type { AbstractUIServer } from './ui-server/AbstractUIServer'; -import UIServerFactory from './ui-server/UIServerFactory'; const moduleName = 'Bootstrap'; -const missingChargingStationsConfigurationExitCode = 1; -const noChargingStationTemplatesExitCode = 2; +enum exitCodes { + missingChargingStationsConfiguration = 1, + noChargingStationTemplates = 2, +} export class Bootstrap { private static instance: Bootstrap | null = null; @@ -51,7 +54,7 @@ export class Bootstrap { this.workerScript = path.join( path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../'), 'charging-station', - 'ChargingStationWorker' + path.extname(fileURLToPath(import.meta.url)) + `ChargingStationWorker${path.extname(fileURLToPath(import.meta.url))}` ); this.initialize(); Configuration.getUIServer().enabled === true && @@ -75,6 +78,9 @@ export class Bootstrap { public async start(): Promise { if (isMainThread && this.started === false) { try { + // Enable unconditionally for now + this.logUnhandledRejection(); + this.logUncaughtException(); this.initialize(); await this.storage?.open(); await this.workerImplementation.start(); @@ -92,9 +98,7 @@ export class Bootstrap { } catch (error) { console.error( chalk.red( - 'Error at starting charging station with template file ' + - stationTemplateUrl.file + - ': ' + `Error at starting charging station with template file ${stationTemplateUrl.file}: ` ), error ); @@ -104,13 +108,13 @@ export class Bootstrap { console.warn( chalk.yellow("'stationTemplateUrls' not defined or empty in configuration, exiting") ); - process.exit(missingChargingStationsConfigurationExitCode); + process.exit(exitCodes.missingChargingStationsConfiguration); } if (this.numberOfChargingStations === 0) { console.warn( chalk.yellow('No charging station template enabled in configuration, exiting') ); - process.exit(noChargingStationTemplatesExitCode); + process.exit(exitCodes.noChargingStationTemplates); } else { console.info( chalk.green( @@ -173,9 +177,7 @@ export class Bootstrap { poolOptions: { workerChoiceStrategy: Configuration.getWorker().poolStrategy, }, - messageHandler: this.messageHandler.bind(this) as ( - msg: ChargingStationWorkerMessage - ) => void, + messageHandler: this.messageHandler.bind(this) as MessageHandler, } )); } @@ -222,11 +224,25 @@ export class Bootstrap { private workerEventStarted = (data: ChargingStationData) => { this.uiServer?.chargingStations.set(data.stationInfo.hashId, data); ++this.numberOfStartedChargingStations; + logger.info( + `${this.logPrefix()} ${moduleName}.workerEventStarted: Charging station ${ + data.stationInfo.chargingStationId + } (hashId: ${data.stationInfo.hashId}) started (${ + this.numberOfStartedChargingStations + } started from ${this.numberOfChargingStations})` + ); }; private workerEventStopped = (data: ChargingStationData) => { this.uiServer?.chargingStations.set(data.stationInfo.hashId, data); --this.numberOfStartedChargingStations; + logger.info( + `${this.logPrefix()} ${moduleName}.workerEventStopped: Charging station ${ + data.stationInfo.chargingStationId + } (hashId: ${data.stationInfo.hashId}) stopped (${ + this.numberOfStartedChargingStations + } started from ${this.numberOfChargingStations})` + ); }; private workerEventUpdated = (data: ChargingStationData) => { @@ -244,6 +260,18 @@ export class Bootstrap { this.initializeWorkerImplementation(); } + private logUncaughtException(): void { + process.on('uncaughtException', (error: Error) => { + console.error(chalk.red('Uncaught exception: '), error); + }); + } + + private logUnhandledRejection(): void { + process.on('unhandledRejection', (reason: unknown) => { + console.error(chalk.red('Unhandled rejection: '), reason); + }); + } + private async startChargingStation( index: number, stationTemplateUrl: StationTemplateUrl