X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fperformance%2Fstorage%2FJSONFileStorage.ts;h=7e23365ef77212cab7cf9f8ef690d214edad9ef7;hb=dc100e978337264ceade1c7bbd67faa967c874e1;hp=25ba236703f4b60393b963fa0f349b7c01ea9b9d;hpb=a6ceb16a6b67653adaa0b40cd057826c71f44f36;p=e-mobility-charging-stations-simulator.git diff --git a/src/performance/storage/JSONFileStorage.ts b/src/performance/storage/JSONFileStorage.ts index 25ba2367..7e23365e 100644 --- a/src/performance/storage/JSONFileStorage.ts +++ b/src/performance/storage/JSONFileStorage.ts @@ -5,6 +5,7 @@ import FileUtils from '../../utils/FileUtils'; import Statistics from '../../types/Statistics'; import { Storage } from './Storage'; import fs from 'fs'; +import lockfile from 'proper-lockfile'; export class JSONFileStorage extends Storage { private fd: number | null = null; @@ -16,19 +17,33 @@ export class JSONFileStorage extends Storage { public storePerformanceStatistics(performanceStatistics: Statistics): void { this.checkPerformanceRecordsFile(); - fs.readFile(this.dbName, 'utf-8', (error, data) => { - if (error) { - FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error); - } else { - const performanceRecords: Statistics[] = data ? JSON.parse(data) as Statistics[] : []; - performanceRecords.push(performanceStatistics); - fs.writeFile(this.dbName, JSON.stringify(performanceRecords, null, 2), 'utf-8', (err) => { - if (err) { - FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, err); - } - }); - } - }); + 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 */ }); } public open(): void { @@ -37,7 +52,7 @@ export class JSONFileStorage extends Storage { this.fd = fs.openSync(this.dbName, 'a+'); } } catch (error) { - FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error); + FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error as NodeJS.ErrnoException); } } @@ -48,12 +63,12 @@ export class JSONFileStorage extends Storage { this.fd = null; } } catch (error) { - FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error); + FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error as NodeJS.ErrnoException); } } private checkPerformanceRecordsFile(): void { - if (!this.fd) { + if (!this?.fd) { throw new Error(`${this.logPrefix} Performance records '${this.dbName}' file descriptor not found`); } }