refactor: cleanup boot notification handling internal handling
[e-mobility-charging-stations-simulator.git] / src / charging-station / Bootstrap.ts
index 4f72d6dfdffef0ca7a65cb24a2103f19558ced6f..d12f78f9b326e79152a11e33d3ccf9f09f2bd2d6 100644 (file)
@@ -18,7 +18,6 @@ import {
   type ChargingStationInfo,
   type ChargingStationOptions,
   type ChargingStationWorkerData,
-  type ChargingStationWorkerEventError,
   type ChargingStationWorkerMessage,
   type ChargingStationWorkerMessageData,
   ChargingStationWorkerMessageEvents,
@@ -43,7 +42,7 @@ import {
   logger,
   logPrefix
 } from '../utils/index.js'
-import { type WorkerAbstract, WorkerFactory } from '../worker/index.js'
+import { DEFAULT_ELEMENTS_PER_WORKER, type WorkerAbstract, WorkerFactory } from '../worker/index.js'
 import { buildTemplateName, waitChargingStationEvents } from './Helpers.js'
 import type { AbstractUIServer } from './ui-server/AbstractUIServer.js'
 import { UIServerFactory } from './ui-server/UIServerFactory.js'
@@ -115,9 +114,17 @@ export class Bootstrap extends EventEmitter {
     )
   }
 
+  public get numberOfProvisionedChargingStations (): number {
+    return [...this.templateStatistics.values()].reduce(
+      (accumulator, value) => accumulator + value.provisioned,
+      0
+    )
+  }
+
   public getState (): SimulatorState {
     return {
       version: this.version,
+      configuration: Configuration.getConfigurationData(),
       started: this.started,
       templateStatistics: this.templateStatistics
     }
@@ -167,15 +174,6 @@ export class Bootstrap extends EventEmitter {
           ChargingStationWorkerMessageEvents.performanceStatistics,
           this.workerEventPerformanceStatistics
         )
-        this.on(
-          ChargingStationWorkerMessageEvents.workerElementError,
-          (eventError: ChargingStationWorkerEventError) => {
-            logger.error(
-              `${this.logPrefix()} ${moduleName}.start: Error occurred while handling '${eventError.event}' event on worker:`,
-              eventError
-            )
-          }
-        )
         // eslint-disable-next-line @typescript-eslint/unbound-method
         if (isAsyncFunction(this.workerImplementation?.start)) {
           await this.workerImplementation.start()
@@ -227,9 +225,13 @@ export class Bootstrap extends EventEmitter {
         )
         console.info(
           chalk.green(
-            `Charging stations simulator ${
-              this.version
-            } started with ${this.numberOfConfiguredChargingStations} configured charging station(s) from ${this.numberOfChargingStationTemplates} charging station template(s) and ${
+            `Charging stations simulator ${this.version} started with ${
+              this.numberOfConfiguredChargingStations
+            } configured and ${
+              this.numberOfProvisionedChargingStations
+            } provisioned charging station(s) from ${
+              this.numberOfChargingStationTemplates
+            } charging station template(s) and ${
               Configuration.workerDynamicPoolInUse() ? `${workerConfiguration.poolMinSize}/` : ''
             }${this.workerImplementation?.size}${
               Configuration.workerPoolInUse() ? `/${workerConfiguration.poolMaxSize}` : ''
@@ -337,15 +339,22 @@ export class Bootstrap extends EventEmitter {
     let elementsPerWorker: number
     switch (workerConfiguration.elementsPerWorker) {
       case 'all':
-        elementsPerWorker = this.numberOfConfiguredChargingStations
+        elementsPerWorker =
+          this.numberOfConfiguredChargingStations + this.numberOfProvisionedChargingStations
         break
       case 'auto':
-      default:
         elementsPerWorker =
-          this.numberOfConfiguredChargingStations > availableParallelism()
-            ? Math.round(this.numberOfConfiguredChargingStations / (availableParallelism() * 1.5))
+          this.numberOfConfiguredChargingStations + this.numberOfProvisionedChargingStations >
+          availableParallelism()
+            ? Math.round(
+              (this.numberOfConfiguredChargingStations +
+                  this.numberOfProvisionedChargingStations) /
+                  (availableParallelism() * 1.5)
+            )
             : 1
         break
+      default:
+        elementsPerWorker = workerConfiguration.elementsPerWorker ?? DEFAULT_ELEMENTS_PER_WORKER
     }
     this.workerImplementation = WorkerFactory.getWorkerImplementation<
     ChargingStationWorkerData,
@@ -368,7 +377,9 @@ export class Bootstrap extends EventEmitter {
         poolOptions: {
           messageHandler: this.messageHandler.bind(this) as MessageHandler<Worker>,
           ...(workerConfiguration.resourceLimits != null && {
-            workerOptions: { resourceLimits: workerConfiguration.resourceLimits }
+            workerOptions: {
+              resourceLimits: workerConfiguration.resourceLimits
+            }
           })
         }
       }
@@ -379,50 +390,50 @@ export class Bootstrap extends EventEmitter {
     msg: ChargingStationWorkerMessage<ChargingStationWorkerMessageData>
   ): void {
     // logger.debug(
-    //   `${this.logPrefix()} ${moduleName}.messageHandler: Worker channel message received: ${JSON.stringify(
+    //   `${this.logPrefix()} ${moduleName}.messageHandler: Charging station worker message received: ${JSON.stringify(
     //     msg,
     //     undefined,
     //     2
     //   )}`
     // )
+    // Skip worker message events processing
+    // eslint-disable-next-line @typescript-eslint/dot-notation
+    if (msg['uuid'] != null) {
+      return
+    }
+    const { event, data } = msg
     try {
-      switch (msg.event) {
+      switch (event) {
         case ChargingStationWorkerMessageEvents.added:
-          this.emit(ChargingStationWorkerMessageEvents.added, msg.data)
+          this.emit(ChargingStationWorkerMessageEvents.added, data)
           break
         case ChargingStationWorkerMessageEvents.deleted:
-          this.emit(ChargingStationWorkerMessageEvents.deleted, msg.data)
+          this.emit(ChargingStationWorkerMessageEvents.deleted, data)
           break
         case ChargingStationWorkerMessageEvents.started:
-          this.emit(ChargingStationWorkerMessageEvents.started, msg.data)
+          this.emit(ChargingStationWorkerMessageEvents.started, data)
           break
         case ChargingStationWorkerMessageEvents.stopped:
-          this.emit(ChargingStationWorkerMessageEvents.stopped, msg.data)
+          this.emit(ChargingStationWorkerMessageEvents.stopped, data)
           break
         case ChargingStationWorkerMessageEvents.updated:
-          this.emit(ChargingStationWorkerMessageEvents.updated, msg.data)
+          this.emit(ChargingStationWorkerMessageEvents.updated, data)
           break
         case ChargingStationWorkerMessageEvents.performanceStatistics:
-          this.emit(ChargingStationWorkerMessageEvents.performanceStatistics, msg.data)
-          break
-        case ChargingStationWorkerMessageEvents.addedWorkerElement:
-          this.emit(ChargingStationWorkerMessageEvents.addWorkerElement, msg.data)
-          break
-        case ChargingStationWorkerMessageEvents.workerElementError:
-          this.emit(ChargingStationWorkerMessageEvents.workerElementError, msg.data)
+          this.emit(ChargingStationWorkerMessageEvents.performanceStatistics, data)
           break
         default:
           throw new BaseError(
-            `Unknown charging station worker event: '${
-              msg.event
-            }' received with data: ${JSON.stringify(msg.data, undefined, 2)}`
+            `Unknown charging station worker message event: '${event}' received with data: ${JSON.stringify(
+              data,
+              undefined,
+              2
+            )}`
           )
       }
     } catch (error) {
       logger.error(
-        `${this.logPrefix()} ${moduleName}.messageHandler: Error occurred while handling '${
-          msg.event
-        }' event:`,
+        `${this.logPrefix()} ${moduleName}.messageHandler: Error occurred while handling charging station worker message event '${event}':`,
         error
       )
     }
@@ -435,7 +446,9 @@ export class Bootstrap extends EventEmitter {
         data.stationInfo.chargingStationId
       } (hashId: ${data.stationInfo.hashId}) added (${
         this.numberOfAddedChargingStations
-      } added from ${this.numberOfConfiguredChargingStations} configured charging station(s))`
+      } added from ${this.numberOfConfiguredChargingStations} configured and ${
+        this.numberOfProvisionedChargingStations
+      } provisioned charging station(s))`
     )
   }
 
@@ -450,7 +463,9 @@ export class Bootstrap extends EventEmitter {
         data.stationInfo.chargingStationId
       } (hashId: ${data.stationInfo.hashId}) deleted (${
         this.numberOfAddedChargingStations
-      } added from ${this.numberOfConfiguredChargingStations} configured charging station(s))`
+      } added from ${this.numberOfConfiguredChargingStations} configured and ${
+        this.numberOfProvisionedChargingStations
+      } provisioned charging station(s))`
     )
   }
 
@@ -507,6 +522,7 @@ export class Bootstrap extends EventEmitter {
         const templateName = buildTemplateName(stationTemplateUrl.file)
         this.templateStatistics.set(templateName, {
           configured: stationTemplateUrl.numberOfStations,
+          provisioned: stationTemplateUrl.provisionedNumberOfStations ?? 0,
           added: 0,
           started: 0,
           indexes: new Set<number>()