-// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
+// Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
import { EventEmitter } from 'node:events'
import { dirname, extname, join } from 'node:path'
import process, { exit } from 'node:process'
import { fileURLToPath } from 'node:url'
+import type { Worker } from 'worker_threads'
import chalk from 'chalk'
-import { availableParallelism } from 'poolifier'
+import { type MessageHandler, availableParallelism } from 'poolifier'
import { waitChargingStationEvents } from './Helpers.js'
import type { AbstractUIServer } from './ui-server/AbstractUIServer.js'
generateUUID,
handleUncaughtException,
handleUnhandledRejection,
+ isAsyncFunction,
isNotEmptyArray,
logPrefix,
logger
succeeded = 0,
missingChargingStationsConfiguration = 1,
noChargingStationTemplates = 2,
- gracefulShutdownError = 3,
+ gracefulShutdownError = 3
}
export class Bootstrap extends EventEmitter {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
for (const stationTemplateUrl of Configuration.getStationTemplateUrls()!) {
try {
- const nbStations = stationTemplateUrl.numberOfStations ?? 0
+ const nbStations = stationTemplateUrl.numberOfStations
for (let index = 1; index <= nbStations; index++) {
await this.startChargingStation(index, stationTemplateUrl)
}
: ''
} worker(s) concurrently running in '${workerConfiguration.processType}' mode${
this.workerImplementation?.maxElementsPerWorker != null
- ? ` (${this.workerImplementation?.maxElementsPerWorker} charging station(s) per worker)`
+ ? ` (${this.workerImplementation.maxElementsPerWorker} charging station(s) per worker)`
: ''
}`
)
private async waitChargingStationsStopped (): Promise<string> {
return await new Promise<string>((resolve, reject) => {
const waitTimeout = setTimeout(() => {
- const message = `Timeout ${formatDurationMilliSeconds(
+ const timeoutMessage = `Timeout ${formatDurationMilliSeconds(
Constants.STOP_CHARGING_STATIONS_TIMEOUT
)} reached at stopping charging stations`
- console.warn(chalk.yellow(message))
- reject(new Error(message))
+ console.warn(chalk.yellow(timeoutMessage))
+ reject(new Error(timeoutMessage))
}, Constants.STOP_CHARGING_STATIONS_TIMEOUT)
waitChargingStationEvents(
this,
ChargingStationWorkerMessageEvents.stopped,
- this.numberOfChargingStations
+ this.numberOfStartedChargingStations
)
.then(() => {
resolve('Charging stations stopped')
private initializeWorkerImplementation (workerConfiguration: WorkerConfiguration): void {
let elementsPerWorker: number | undefined
- switch (workerConfiguration?.elementsPerWorker) {
+ switch (workerConfiguration.elementsPerWorker) {
case 'auto':
elementsPerWorker =
this.numberOfChargingStations > availableParallelism()
poolMinSize: workerConfiguration.poolMinSize!,
elementsPerWorker: elementsPerWorker ?? (workerConfiguration.elementsPerWorker as number),
poolOptions: {
- messageHandler: this.messageHandler.bind(this) as (message: unknown) => void,
+ messageHandler: this.messageHandler.bind(this) as MessageHandler<Worker>,
workerOptions: { resourceLimits: workerConfiguration.resourceLimits }
}
}
}
private readonly workerEventPerformanceStatistics = (data: Statistics): void => {
- this.storage?.storePerformanceStatistics(data) as undefined
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ if (isAsyncFunction(this.storage?.storePerformanceStatistics)) {
+ (
+ this.storage.storePerformanceStatistics as (
+ performanceStatistics: Statistics
+ ) => Promise<void>
+ )(data).catch(Constants.EMPTY_FUNCTION)
+ } else {
+ (this.storage?.storePerformanceStatistics as (performanceStatistics: Statistics) => void)(
+ data
+ )
+ }
}
private initializeCounters (): void {
if (isNotEmptyArray(stationTemplateUrls)) {
this.numberOfChargingStationTemplates = stationTemplateUrls.length
for (const stationTemplateUrl of stationTemplateUrls) {
- this.numberOfChargingStations += stationTemplateUrl.numberOfStations ?? 0
+ this.numberOfChargingStations += stationTemplateUrl.numberOfStations
}
} else {
console.warn(
private gracefulShutdown (): void {
this.stop()
.then(() => {
- console.info(`${chalk.green('Graceful shutdown')}`)
+ console.info(chalk.green('Graceful shutdown'))
this.uiServer?.stop()
// stop() asks for charging stations to stop by default
this.waitChargingStationsStopped()
exit(exitCodes.gracefulShutdownError)
})
})
- .catch((error) => {
+ .catch(error => {
console.error(chalk.red('Error while shutdowning charging stations simulator: '), error)
exit(exitCodes.gracefulShutdownError)
})