X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FIdTagsCache.ts;h=5e0ab0b8f0778c2fbf02333c579657387a5c1d5f;hb=be1e907c6de583ad192c9566943252bbde19aa51;hp=8d4027839851151374d23c795d04520d5fa9ee0f;hpb=32e8c8a50f321cf046fc162f24421cd1d5589200;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/IdTagsCache.ts b/src/charging-station/IdTagsCache.ts index 8d402783..5e0ab0b8 100644 --- a/src/charging-station/IdTagsCache.ts +++ b/src/charging-station/IdTagsCache.ts @@ -1,13 +1,21 @@ -import fs from 'node:fs'; +import { type FSWatcher, readFileSync } from 'node:fs'; -import { type ChargingStation, ChargingStationUtils } from './internal'; +import type { ChargingStation } from './ChargingStation'; +import { getIdTagsFile } from './Helpers'; import { FileType, IdTagDistribution } from '../types'; -import { FileUtils, Utils, logger } from '../utils'; - -type IdTagsCacheValueType = { +import { + handleFileException, + isNotEmptyString, + logPrefix, + logger, + secureRandom, + watchJsonFile, +} from '../utils'; + +interface IdTagsCacheValueType { idTags: string[]; - idTagsFileWatcher: fs.FSWatcher | undefined; -}; + idTagsFileWatcher: FSWatcher | undefined; +} export class IdTagsCache { private static instance: IdTagsCache | null = null; @@ -26,13 +34,22 @@ export class IdTagsCache { return IdTagsCache.instance; } + /** + * Gets one idtag from the cache given the distribution + * Must be called after checking the cache is not an empty array + * + * @param distribution - + * @param chargingStation - + * @param connectorId - + * @returns + */ public getIdTag( distribution: IdTagDistribution, chargingStation: ChargingStation, - connectorId: number + connectorId: number, ): string { const hashId = chargingStation.stationInfo.hashId; - const idTagsFile = ChargingStationUtils.getIdTagsFile(chargingStation.stationInfo); + const idTagsFile = getIdTagsFile(chargingStation.stationInfo)!; switch (distribution) { case IdTagDistribution.RANDOM: return this.getRandomIdTag(hashId, idTagsFile); @@ -45,6 +62,13 @@ export class IdTagsCache { } } + /** + * Gets all idtags from the cache + * Must be called after checking the cache is not an empty array + * + * @param file - + * @returns + */ public getIdTags(file: string): string[] | undefined { if (this.hasIdTagsCache(file) === false) { this.setIdTagsCache(file, this.getIdTagsFromFile(file)); @@ -53,41 +77,43 @@ export class IdTagsCache { } public deleteIdTags(file: string): boolean { - return this.deleteIdTagsCache(file); + return this.deleteIdTagsCache(file) && this.deleteIdTagsCacheIndexes(file); } private getRandomIdTag(hashId: string, file: string): string { - const idTags = this.getIdTags(file); + const idTags = this.getIdTags(file)!; const addressableKey = this.getIdTagsCacheIndexesAddressableKey(file, hashId); this.idTagsCachesAddressableIndexes.set( addressableKey, - Math.floor(Utils.secureRandom() * idTags.length) + Math.floor(secureRandom() * idTags.length), ); - return idTags[this.idTagsCachesAddressableIndexes.get(addressableKey)]; + return idTags[this.idTagsCachesAddressableIndexes.get(addressableKey)!]; } private getRoundRobinIdTag(hashId: string, file: string): string { - const idTags = this.getIdTags(file); + const idTags = this.getIdTags(file)!; const addressableKey = this.getIdTagsCacheIndexesAddressableKey(file, hashId); const idTagIndex = this.idTagsCachesAddressableIndexes.get(addressableKey) ?? 0; const idTag = idTags[idTagIndex]; this.idTagsCachesAddressableIndexes.set( addressableKey, - idTagIndex === idTags.length - 1 ? 0 : idTagIndex + 1 + idTagIndex === idTags.length - 1 ? 0 : idTagIndex + 1, ); return idTag; } private getConnectorAffinityIdTag(chargingStation: ChargingStation, connectorId: number): string { - const file = ChargingStationUtils.getIdTagsFile(chargingStation.stationInfo); - const idTags = this.getIdTags(file); - const hashId = chargingStation.stationInfo.hashId; - const addressableKey = this.getIdTagsCacheIndexesAddressableKey(file, hashId); + const file = getIdTagsFile(chargingStation.stationInfo)!; + const idTags = this.getIdTags(file)!; + const addressableKey = this.getIdTagsCacheIndexesAddressableKey( + file, + chargingStation.stationInfo.hashId, + ); this.idTagsCachesAddressableIndexes.set( addressableKey, - (chargingStation.index - 1 + (connectorId - 1)) % idTags.length + (chargingStation.index - 1 + (connectorId - 1)) % idTags.length, ); - return idTags[this.idTagsCachesAddressableIndexes.get(addressableKey)]; + return idTags[this.idTagsCachesAddressableIndexes.get(addressableKey)!]; } private hasIdTagsCache(file: string): boolean { @@ -97,32 +123,32 @@ export class IdTagsCache { private setIdTagsCache(file: string, idTags: string[]) { return this.idTagsCaches.set(file, { idTags, - idTagsFileWatcher: FileUtils.watchJsonFile( + idTagsFileWatcher: watchJsonFile( file, FileType.Authorization, this.logPrefix(file), undefined, (event, filename) => { - if (Utils.isNotEmptyString(filename) && event === 'change') { + if (isNotEmptyString(filename) && event === 'change') { try { logger.debug( - `${this.logPrefix(file)} ${FileType.Authorization} file have changed, reload` + `${this.logPrefix(file)} ${FileType.Authorization} file have changed, reload`, ); this.deleteIdTagsCache(file); this.deleteIdTagsCacheIndexes(file); } catch (error) { - FileUtils.handleFileException( + handleFileException( file, FileType.Authorization, error as NodeJS.ErrnoException, this.logPrefix(file), { throwError: false, - } + }, ); } } - } + }, ), }); } @@ -136,12 +162,14 @@ export class IdTagsCache { return this.idTagsCaches.delete(file); } - private deleteIdTagsCacheIndexes(file: string): void { + private deleteIdTagsCacheIndexes(file: string): boolean { + const deleted: boolean[] = []; for (const [key] of this.idTagsCachesAddressableIndexes) { if (key.startsWith(file)) { - this.idTagsCachesAddressableIndexes.delete(key); + deleted.push(this.idTagsCachesAddressableIndexes.delete(key)); } } + return !deleted.some((value) => value === false); } private getIdTagsCacheIndexesAddressableKey(prefix: string, uid: string): string { @@ -149,26 +177,22 @@ export class IdTagsCache { } private getIdTagsFromFile(file: string): string[] { - let idTags: string[] = []; - if (file) { + if (isNotEmptyString(file)) { try { - // Load id tags file - idTags = JSON.parse(fs.readFileSync(file, 'utf8')) as string[]; + return JSON.parse(readFileSync(file, 'utf8')) as string[]; } catch (error) { - FileUtils.handleFileException( + handleFileException( file, FileType.Authorization, error as NodeJS.ErrnoException, - this.logPrefix(file) + this.logPrefix(file), ); } - } else { - logger.info(`${this.logPrefix(file)} No id tags file given`); } - return idTags; + return []; } private logPrefix = (file: string): string => { - return Utils.logPrefix(` Id tags cache for id tags file '${file}' |`); + return logPrefix(` Id tags cache for id tags file '${file}' |`); }; }