X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fperformance%2Fstorage%2FJsonFileStorage.ts;h=58680181f7499b858e485ea828e6f969910b78f9;hb=3f0734367ba34b15eb24c7d1e344ad8ae51a3d0d;hp=8a8808e9baa7af069a2834a2afe14a796ccaca1d;hpb=e7aeea18e189dd087c8f951cf77a253e2818ae90;p=e-mobility-charging-stations-simulator.git diff --git a/src/performance/storage/JsonFileStorage.ts b/src/performance/storage/JsonFileStorage.ts index 8a8808e9..58680181 100644 --- a/src/performance/storage/JsonFileStorage.ts +++ b/src/performance/storage/JsonFileStorage.ts @@ -1,14 +1,23 @@ -// Copyright Jerome Benoit. 2021. All Rights Reserved. +// Copyright Jerome Benoit. 2021-2023. All Rights Reserved. + +import { closeSync, existsSync, mkdirSync, openSync, writeSync } from 'node:fs'; +import { dirname } from 'node:path'; -import Constants from '../../utils/Constants'; -import FileUtils from '../../utils/FileUtils'; -import Statistics from '../../types/Statistics'; import { Storage } from './Storage'; -import fs from 'fs'; -import lockfile from 'proper-lockfile'; +import { BaseError } from '../../exception'; +import { FileType, type Statistics } from '../../types'; +import { + AsyncLock, + AsyncLockType, + JSONStringifyWithMapSupport, + handleFileException, + isNullOrUndefined, +} from '../../utils'; export class JsonFileStorage extends Storage { - private fd: number | null = null; + private static performanceRecords: Map; + + private fd?: number; constructor(storageUri: string, logPrefix: string) { super(storageUri, logPrefix); @@ -17,82 +26,64 @@ export class JsonFileStorage extends Storage { public storePerformanceStatistics(performanceStatistics: Statistics): void { this.checkPerformanceRecordsFile(); - lockfile - .lock(this.dbName, { stale: 5000, retries: 3 }) - .then(async (release) => { - try { - const fileData = fs.readFileSync(this.dbName, 'utf8'); - const performanceRecords: Statistics[] = fileData - ? (JSON.parse(fileData) as Statistics[]) - : []; - performanceRecords.push(performanceStatistics); - fs.writeFileSync( - this.dbName, - JSON.stringify( - performanceRecords, - (key, value) => { - if (value instanceof Map) { - return { - dataType: 'Map', - value: [...value], - }; - } - return value as Statistics; - }, - 2 - ), - 'utf8' - ); - } catch (error) { - FileUtils.handleFileException( - this.logPrefix, - Constants.PERFORMANCE_RECORDS_FILETYPE, - this.dbName, - error as NodeJS.ErrnoException - ); - } - await release(); - }) - .catch(() => { - /* This is intentional */ - }); + JsonFileStorage.performanceRecords.set(performanceStatistics.id, performanceStatistics); + AsyncLock.runExclusive(AsyncLockType.performance, () => { + writeSync( + this.fd!, + JSONStringifyWithMapSupport([...JsonFileStorage.performanceRecords.values()], 2), + 0, + 'utf8', + ); + }).catch((error) => { + handleFileException( + this.dbName, + FileType.PerformanceRecords, + error as NodeJS.ErrnoException, + this.logPrefix, + ); + }); } public open(): void { + JsonFileStorage.performanceRecords = new Map(); try { - if (!this?.fd) { - this.fd = fs.openSync(this.dbName, 'a+'); + if (isNullOrUndefined(this?.fd)) { + if (!existsSync(dirname(this.dbName))) { + mkdirSync(dirname(this.dbName), { recursive: true }); + } + this.fd = openSync(this.dbName, 'w'); } } catch (error) { - FileUtils.handleFileException( - this.logPrefix, - Constants.PERFORMANCE_RECORDS_FILETYPE, + handleFileException( this.dbName, - error as NodeJS.ErrnoException + FileType.PerformanceRecords, + error as NodeJS.ErrnoException, + this.logPrefix, ); } } public close(): void { + JsonFileStorage.performanceRecords.clear(); try { if (this?.fd) { - fs.closeSync(this.fd); - this.fd = null; + closeSync(this.fd); + delete this?.fd; } } catch (error) { - FileUtils.handleFileException( - this.logPrefix, - Constants.PERFORMANCE_RECORDS_FILETYPE, + handleFileException( this.dbName, - error as NodeJS.ErrnoException + FileType.PerformanceRecords, + error as NodeJS.ErrnoException, + this.logPrefix, ); } } private checkPerformanceRecordsFile(): void { if (!this?.fd) { - throw new Error( - `${this.logPrefix} Performance records '${this.dbName}' file descriptor not found` + throw new BaseError( + `${this.logPrefix} Performance records '${this.dbName}' file descriptor not found`, ); } }