Use a map to store OCPP command statistics
[e-mobility-charging-stations-simulator.git] / src / performance / storage / JSONFileStorage.ts
1 // Copyright Jerome Benoit. 2021. All Rights Reserved.
2
3 import Constants from '../../utils/Constants';
4 import FileUtils from '../../utils/FileUtils';
5 import Statistics from '../../types/Statistics';
6 import { Storage } from './Storage';
7 import fs from 'fs';
8 import lockfile from 'proper-lockfile';
9
10 export class JSONFileStorage extends Storage {
11 private fd: number | null = null;
12
13 constructor(storageURI: string, logPrefix: string) {
14 super(storageURI, logPrefix);
15 this.dbName = this.storageURI.pathname;
16 }
17
18 public storePerformanceStatistics(performanceStatistics: Statistics): void {
19 this.checkPerformanceRecordsFile();
20 lockfile.lock(this.dbName, { stale: 5000, retries: 3 })
21 .then(async (release) => {
22 try {
23 const fileData = fs.readFileSync(this.dbName, 'utf8');
24 const performanceRecords: Statistics[] = fileData ? JSON.parse(fileData) as Statistics[] : [];
25 performanceRecords.push(performanceStatistics);
26 fs.writeFileSync(this.dbName,
27 JSON.stringify(performanceRecords,
28 (key, value) => {
29 if (value instanceof Map) {
30 return {
31 dataType: 'Map',
32 value: [...value]
33 };
34 }
35 return value as Statistics;
36 },
37 2),
38 'utf8');
39 } catch (error) {
40 FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error);
41 }
42 await release();
43 })
44 .catch(() => { /* This is intentional */ });
45 }
46
47 public open(): void {
48 try {
49 if (!this?.fd) {
50 this.fd = fs.openSync(this.dbName, 'a+');
51 }
52 } catch (error) {
53 FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error);
54 }
55 }
56
57 public close(): void {
58 try {
59 if (this?.fd) {
60 fs.closeSync(this.fd);
61 this.fd = null;
62 }
63 } catch (error) {
64 FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error);
65 }
66 }
67
68 private checkPerformanceRecordsFile(): void {
69 if (!this?.fd) {
70 throw new Error(`${this.logPrefix} Performance records '${this.dbName}' file descriptor not found`);
71 }
72 }
73 }