feat: allow to provision number of stations by template
authorJérôme Benoit <jerome.benoit@sap.com>
Tue, 26 Mar 2024 19:23:20 +0000 (20:23 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Tue, 26 Mar 2024 19:23:20 +0000 (20:23 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
README.md
src/assets/config-template.json
src/charging-station/Bootstrap.ts
src/charging-station/SharedLRUCache.ts
src/types/ConfigurationData.ts
src/types/SimulatorState.ts
src/types/Statistics.ts
src/utils/Configuration.ts

index e897431b90ecdc3602dcc9ba78fbf98c81ce5985..7445d387e5341ee268b5efedbc37d9082291e34b 100644 (file)
--- a/README.md
+++ b/README.md
@@ -147,7 +147,7 @@ But the modifications to test have to be done to the files in the build target d
 | worker                     |                                              | {<br />"processType": "workerSet",<br />"startDelay": 500,<br />"elementAddDelay": 0,<br />"elementsPerWorker": 'auto',<br />"poolMinSize": 4,<br />"poolMaxSize": 16<br />}                                                  | {<br />processType?: WorkerProcessType;<br />startDelay?: number;<br />elementAddDelay?: number;<br />elementsPerWorker?: number \| 'auto' \| 'all';<br />poolMinSize?: number;<br />poolMaxSize?: number;<br />resourceLimits?: ResourceLimits;<br />}                         | Worker configuration section:<br />- _processType_: worker threads process type (`workerSet`/`fixedPool`/`dynamicPool`)<br />- _startDelay_: milliseconds to wait at worker threads startup (only for `workerSet` worker threads process type)<br />- _elementAddDelay_: milliseconds to wait between charging station add<br />- _elementsPerWorker_: number of charging stations per worker threads for the `workerSet` process type (`auto` means (number of stations) / (number of CPUs) \* 1.5 if (number of stations) > (number of CPUs), otherwise 1; `all` means a unique worker will run all charging stations)<br />- _poolMinSize_: worker threads pool minimum number of threads</br >- _poolMaxSize_: worker threads pool maximum number of threads<br />- _resourceLimits_: worker threads [resource limits](https://nodejs.org/api/worker_threads.html#new-workerfilename-options) object option |
 | uiServer                   |                                              | {<br />"enabled": false,<br />"type": "ws",<br />"version": "1.1",<br />"options": {<br />"host": "localhost",<br />"port": 8080<br />}<br />}                                                                                | {<br />enabled?: boolean;<br />type?: ApplicationProtocol;<br />version?: ApplicationProtocolVersion;<br />options?: ServerOptions;<br />authentication?: {<br />enabled: boolean;<br />type: AuthenticationType;<br />username?: string;<br />password?: string;<br />}<br />} | UI server configuration section:<br />- _enabled_: enable UI server<br />- _type_: 'http' or 'ws'<br />- _version_: HTTP version '1.1' or '2.0'<br />- _options_: node.js net module [listen options](https://nodejs.org/api/net.html#serverlistenoptions-callback)<br />- _authentication_: authentication type configuration section                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 | performanceStorage         |                                              | {<br />"enabled": true,<br />"type": "none",<br />}                                                                                                                                                                           | {<br />enabled?: boolean;<br />type?: string;<br />uri?: string;<br />}                                                                                                                                                                                                         | Performance storage configuration section:<br />- _enabled_: enable performance storage<br />- _type_: 'jsonfile', 'mongodb' or 'none'<br />- _uri_: storage URI                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
-| stationTemplateUrls        |                                              | {}[]                                                                                                                                                                                                                          | {<br />file: string;<br />numberOfStations: number;<br />}[]                                                                                                                                                                                                                    | array of charging station configuration templates URIs configuration section (charging station configuration template file name and number of stations)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+| stationTemplateUrls        |                                              | {}[]                                                                                                                                                                                                                          | {<br />file: string;<br />numberOfStations: number;<br />provisionedNumberOfStations?: number;<br />}[]                                                                                                                                                                         | array of charging station templates URIs configuration section:<br />- _file_: charging station configuration template file relative path<br />- _numberOfStations_: template number of stations at startup<br />- _provisionedNumberOfStations_: template provisioned number of stations after startup                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
 
 #### Worker process model
 
index 0946258fc1b483a4adedfa4b98d70484eae7f703..943e9c5b2c4998b556c614eb80714666e5afbf4c 100644 (file)
@@ -31,7 +31,8 @@
     },
     {
       "file": "keba.station-template.json",
-      "numberOfStations": 2
+      "numberOfStations": 2,
+      "provisionedNumberOfStations": 2
     },
     {
       "file": "abb.station-template.json",
index bb801e74eb1ffd566c7d30af07fa5d65af166d19..5293a9a83c28a9a1791f166606d3ca275f2cbb67 100644 (file)
@@ -114,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
     }
@@ -219,7 +227,7 @@ export class Bootstrap extends EventEmitter {
           chalk.green(
             `Charging stations simulator ${
               this.version
-            } started with ${this.numberOfConfiguredChargingStations} configured charging station(s) from ${this.numberOfChargingStationTemplates} charging station template(s) and ${
+            } 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}` : ''
@@ -327,12 +335,18 @@ export class Bootstrap extends EventEmitter {
     let elementsPerWorker: number
     switch (workerConfiguration.elementsPerWorker) {
       case 'all':
-        elementsPerWorker = this.numberOfConfiguredChargingStations
+        elementsPerWorker =
+          this.numberOfConfiguredChargingStations + this.numberOfProvisionedChargingStations
         break
       case 'auto':
         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:
@@ -422,7 +436,7 @@ 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))`
     )
   }
 
@@ -437,7 +451,7 @@ 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))`
     )
   }
 
@@ -494,6 +508,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>()
index 7f459a4fa1b875bcf1c668d67ac53eaf9a43731f..0da4558d4d46f4c4bd3d98f92eb2a7677856517d 100644 (file)
@@ -19,7 +19,8 @@ export class SharedLRUCache {
   private constructor () {
     this.lruCache = new LRUCache<string, CacheValueType>(
       Bootstrap.getInstance().numberOfChargingStationTemplates +
-        Bootstrap.getInstance().numberOfConfiguredChargingStations
+        Bootstrap.getInstance().numberOfConfiguredChargingStations +
+        Bootstrap.getInstance().numberOfProvisionedChargingStations
     )
   }
 
index 3d5f98a7eebf2131562989ae47121d55c27aceac..ffbb7deca5994abb61e9b5fc4736e4fb14b1cf61 100644 (file)
@@ -25,6 +25,7 @@ export enum SupervisionUrlDistribution {
 export interface StationTemplateUrl {
   file: string
   numberOfStations: number
+  provisionedNumberOfStations?: number
 }
 
 export interface LogConfiguration {
index d3816ede00eb6f69e3a2207fcb88e3864ce0a739..0ba5307897af6e8939bdc05f92ea186df0bf5172 100644 (file)
@@ -1,7 +1,9 @@
+import type { ConfigurationData } from './ConfigurationData.js'
 import type { TemplateStatistics } from './Statistics.js'
 
 export interface SimulatorState {
   version: string
+  configuration: ConfigurationData | undefined
   started: boolean
   templateStatistics: Map<string, TemplateStatistics>
 }
index 81ba1d564e11c5018caabda84e16284968b51f12..4c03dd9d73c62c06f35d432bbc18cf9be62ec082 100644 (file)
@@ -34,6 +34,7 @@ export interface Statistics extends WorkerData {
 
 export interface TemplateStatistics {
   configured: number
+  provisioned: number
   added: number
   started: number
   indexes: Set<number>
index 9356785deaf2af7dfba30ff313d9bfbf82f8ee34..25a1475bc2a5f6ec9a6ea40df049048db9538ad8 100644 (file)
@@ -544,7 +544,7 @@ export class Configuration {
     }
   }
 
-  private static getConfigurationData (): ConfigurationData | undefined {
+  public static getConfigurationData (): ConfigurationData | undefined {
     if (Configuration.configurationData == null) {
       try {
         Configuration.configurationData = JSON.parse(