X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FBootstrap.ts;h=27f4a6073c8c5159c1bfa2b134688e6d6027325a;hb=acfa5fd10b8489f5d85654e654356e65bfd1e0d0;hp=1550f6a7dc8ee92547fda280dbe4f569592f753e;hpb=34c200d5d7239aed80b68da98b664b573bf6e8bd;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/Bootstrap.ts b/src/charging-station/Bootstrap.ts index 1550f6a7..27f4a607 100644 --- a/src/charging-station/Bootstrap.ts +++ b/src/charging-station/Bootstrap.ts @@ -8,7 +8,7 @@ import { isMainThread } from 'node:worker_threads'; import chalk from 'chalk'; import { availableParallelism } from 'poolifier'; -import { waitChargingStationEvents } from './ChargingStationUtils'; +import { waitChargingStationEvents } from './Helpers'; import type { AbstractUIServer } from './ui-server/AbstractUIServer'; import { UIServerFactory } from './ui-server/UIServerFactory'; import { version } from '../../package.json' assert { type: 'json' }; @@ -20,9 +20,13 @@ import { type ChargingStationWorkerMessage, type ChargingStationWorkerMessageData, ChargingStationWorkerMessageEvents, + ConfigurationSection, ProcedureName, type StationTemplateUrl, type Statistics, + type StorageConfiguration, + type UIServerConfiguration, + type WorkerConfiguration, } from '../types'; import { Configuration, @@ -36,7 +40,7 @@ import { logPrefix, logger, } from '../utils'; -import { type WorkerAbstract, WorkerConstants, WorkerFactory } from '../worker'; +import { type WorkerAbstract, WorkerFactory } from '../worker'; const moduleName = 'Bootstrap'; @@ -78,12 +82,19 @@ export class Bootstrap extends EventEmitter { dirname(fileURLToPath(import.meta.url)), `ChargingStationWorker${extname(fileURLToPath(import.meta.url))}`, ); - Configuration.getUIServer().enabled === true && - (this.uiServer = UIServerFactory.getUIServerImplementation(Configuration.getUIServer())); - Configuration.getPerformanceStorage().enabled === true && + const uiServerConfiguration = Configuration.getConfigurationSection( + ConfigurationSection.uiServer, + ); + uiServerConfiguration.enabled === true && + (this.uiServer = UIServerFactory.getUIServerImplementation(uiServerConfiguration)); + const performanceStorageConfiguration = + Configuration.getConfigurationSection( + ConfigurationSection.performanceStorage, + ); + performanceStorageConfiguration.enabled === true && (this.storage = StorageFactory.getStorage( - Configuration.getPerformanceStorage().type, - Configuration.getPerformanceStorage().uri, + performanceStorageConfiguration.type!, + performanceStorageConfiguration.uri!, this.logPrefix(), )); Configuration.setConfigurationChangeCallback(async () => Bootstrap.getInstance().restart()); @@ -98,18 +109,21 @@ export class Bootstrap extends EventEmitter { public async start(): Promise { if (!isMainThread) { - throw new Error('Cannot start charging stations simulator from worker thread'); + throw new BaseError('Cannot start charging stations simulator from worker thread'); } if (this.started === false) { if (this.starting === false) { this.starting = true; this.initializeCounters(); - this.initializeWorkerImplementation(); + const workerConfiguration = Configuration.getConfigurationSection( + ConfigurationSection.worker, + ); + this.initializeWorkerImplementation(workerConfiguration); await this.workerImplementation?.start(); await this.storage?.open(); this.uiServer?.start(); // Start ChargingStation object instance in worker thread - for (const stationTemplateUrl of Configuration.getStationTemplateUrls()) { + for (const stationTemplateUrl of Configuration.getStationTemplateUrls()!) { try { const nbStations = stationTemplateUrl.numberOfStations ?? 0; for (let index = 1; index <= nbStations; index++) { @@ -130,13 +144,13 @@ export class Bootstrap extends EventEmitter { this.version } started with ${this.numberOfChargingStations.toString()} charging station(s) from ${this.numberOfChargingStationTemplates.toString()} configured charging station template(s) and ${ Configuration.workerDynamicPoolInUse() - ? `${Configuration.getWorker().poolMinSize?.toString()}/` + ? `${workerConfiguration.poolMinSize?.toString()}/` : '' }${this.workerImplementation?.size}${ Configuration.workerPoolInUse() - ? `/${Configuration.getWorker().poolMaxSize?.toString()}` + ? `/${workerConfiguration.poolMaxSize?.toString()}` : '' - } worker(s) concurrently running in '${Configuration.getWorker().processType}' mode${ + } worker(s) concurrently running in '${workerConfiguration.processType}' mode${ !isNullOrUndefined(this.workerImplementation?.maxElementsPerWorker) ? ` (${this.workerImplementation?.maxElementsPerWorker} charging station(s) per worker)` : '' @@ -162,7 +176,7 @@ export class Bootstrap extends EventEmitter { public async stop(): Promise { if (!isMainThread) { - throw new Error('Cannot stop charging stations simulator from worker thread'); + throw new BaseError('Cannot stop charging stations simulator from worker thread'); } if (this.started === true) { if (this.stopping === false) { @@ -211,27 +225,25 @@ export class Bootstrap extends EventEmitter { await this.start(); } - private initializeWorkerImplementation(): void { - let elementsPerWorker: number; - if (Configuration.getWorker()?.elementsPerWorker === 'auto') { + private initializeWorkerImplementation(workerConfiguration: WorkerConfiguration): void { + let elementsPerWorker: number | undefined; + if (workerConfiguration?.elementsPerWorker === 'auto') { elementsPerWorker = this.numberOfChargingStations > availableParallelism() - ? Math.round(this.numberOfChargingStations / availableParallelism()) + ? Math.round(this.numberOfChargingStations / (availableParallelism() * 1.5)) : 1; } this.workerImplementation === null && (this.workerImplementation = WorkerFactory.getWorkerImplementation( this.workerScript, - Configuration.getWorker().processType, + workerConfiguration.processType!, { - workerStartDelay: Configuration.getWorker().startDelay, - elementStartDelay: Configuration.getWorker().elementStartDelay, - poolMaxSize: Configuration.getWorker().poolMaxSize, - poolMinSize: Configuration.getWorker().poolMinSize, - elementsPerWorker: - elementsPerWorker ?? (Configuration.getWorker().elementsPerWorker as number), + workerStartDelay: workerConfiguration.startDelay, + elementStartDelay: workerConfiguration.elementStartDelay, + poolMaxSize: workerConfiguration.poolMaxSize!, + poolMinSize: workerConfiguration.poolMinSize!, + elementsPerWorker: elementsPerWorker ?? (workerConfiguration.elementsPerWorker as number), poolOptions: { - workerChoiceStrategy: Configuration.getWorker().poolStrategy, messageHandler: this.messageHandler.bind(this) as (message: unknown) => void, }, }, @@ -245,11 +257,11 @@ export class Bootstrap extends EventEmitter { // `${this.logPrefix()} ${moduleName}.messageHandler: Worker channel message received: ${JSON.stringify( // msg, // null, - // 2 - // )}` + // 2, + // )}`, // ); try { - switch (msg.id) { + switch (msg.event) { case ChargingStationWorkerMessageEvents.started: this.workerEventStarted(msg.data as ChargingStationData); this.emit(ChargingStationWorkerMessageEvents.started, msg.data as ChargingStationData); @@ -269,15 +281,26 @@ export class Bootstrap extends EventEmitter { msg.data as Statistics, ); break; + case ChargingStationWorkerMessageEvents.startWorkerElementError: + logger.error( + `${this.logPrefix()} ${moduleName}.messageHandler: Error occured while starting worker element:`, + msg.data, + ); + this.emit(ChargingStationWorkerMessageEvents.startWorkerElementError, msg.data); + break; + case ChargingStationWorkerMessageEvents.startedWorkerElement: + break; default: throw new BaseError( - `Unknown event type: '${msg.id}' for data: ${JSON.stringify(msg.data, null, 2)}`, + `Unknown charging station worker event: '${ + msg.event + }' received with data: ${JSON.stringify(msg.data, null, 2)}`, ); } } catch (error) { logger.error( `${this.logPrefix()} ${moduleName}.messageHandler: Error occurred while handling '${ - msg.id + msg.event }' event:`, error, ); @@ -319,7 +342,7 @@ export class Bootstrap extends EventEmitter { private initializeCounters() { if (this.initializedCounters === false) { this.resetCounters(); - const stationTemplateUrls = Configuration.getStationTemplateUrls(); + const stationTemplateUrls = Configuration.getStationTemplateUrls()!; if (isNotEmptyArray(stationTemplateUrls)) { this.numberOfChargingStationTemplates = stationTemplateUrls.length; for (const stationTemplateUrl of stationTemplateUrls) {