-} from '../types/ChargingStationWorker';
-import type { StationTemplateUrl } from '../types/ConfigurationData';
-import type { Statistics } from '../types/Statistics';
-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;
-
-export class Bootstrap {
- private static instance: Bootstrap | null = null;
- private workerImplementation: WorkerAbstract<ChargingStationWorkerData> | null;
- private readonly uiServer!: AbstractUIServer;
- private readonly storage!: Storage;
- private numberOfChargingStationTemplates!: number;
- private numberOfChargingStations!: number;
- private numberOfStartedChargingStations!: number;
- private readonly version: string = version;
- private started: boolean;
- private readonly workerScript: string;
-
- private constructor() {
- this.started = false;
- this.workerImplementation = null;
- this.workerScript = path.join(
- path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../'),
- 'charging-station',
- 'ChargingStationWorker' + path.extname(fileURLToPath(import.meta.url))
- );
- this.initialize();
- Configuration.getUIServer().enabled === true &&
- (this.uiServer = UIServerFactory.getUIServerImplementation(Configuration.getUIServer()));
- Configuration.getPerformanceStorage().enabled === true &&
- (this.storage = StorageFactory.getStorage(
- Configuration.getPerformanceStorage().type,
- Configuration.getPerformanceStorage().uri,
- this.logPrefix()
- ));
- Configuration.setConfigurationChangeCallback(async () => Bootstrap.getInstance().restart());
+ ConfigurationSection,
+ ProcedureName,
+ type SimulatorState,
+ type Statistics,
+ type StorageConfiguration,
+ type TemplateStatistics,
+ type UIServerConfiguration,
+ type WorkerConfiguration
+} from '../types/index.js'
+import {
+ Configuration,
+ Constants,
+ formatDurationMilliSeconds,
+ generateUUID,
+ handleUncaughtException,
+ handleUnhandledRejection,
+ isAsyncFunction,
+ isNotEmptyArray,
+ logger,
+ logPrefix
+} from '../utils/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'
+
+const moduleName = 'Bootstrap'
+
+enum exitCodes {
+ succeeded = 0,
+ missingChargingStationsConfiguration = 1,
+ duplicateChargingStationTemplateUrls = 2,
+ noChargingStationTemplates = 3,
+ gracefulShutdownError = 4
+}
+
+export class Bootstrap extends EventEmitter {
+ private static instance: Bootstrap | null = null
+ private workerImplementation?: WorkerAbstract<ChargingStationWorkerData, ChargingStationInfo>
+ private readonly uiServer: AbstractUIServer
+ private storage?: Storage
+ private readonly templateStatistics: Map<string, TemplateStatistics>
+ private readonly version: string = version
+ private started: boolean
+ private starting: boolean
+ private stopping: boolean
+ private uiServerStarted: boolean
+
+ private constructor () {
+ super()
+ for (const signal of ['SIGINT', 'SIGQUIT', 'SIGTERM']) {
+ process.on(signal, this.gracefulShutdown.bind(this))
+ }
+ // Enable unconditionally for now
+ handleUnhandledRejection()
+ handleUncaughtException()
+ this.started = false
+ this.starting = false
+ this.stopping = false
+ this.uiServerStarted = false
+ this.templateStatistics = new Map<string, TemplateStatistics>()
+ this.uiServer = UIServerFactory.getUIServerImplementation(
+ Configuration.getConfigurationSection<UIServerConfiguration>(ConfigurationSection.uiServer)
+ )
+ this.initializeCounters()
+ this.initializeWorkerImplementation(
+ Configuration.getConfigurationSection<WorkerConfiguration>(ConfigurationSection.worker)
+ )
+ Configuration.configurationChangeCallback = async () => {
+ if (isMainThread) {
+ await Bootstrap.getInstance().restart()
+ }
+ }