fix: fix performance records duplication
[e-mobility-charging-stations-simulator.git] / src / performance / storage / JsonFileStorage.ts
CommitLineData
edd13439 1// Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
c27c3eee 2
f1c729e0 3import { closeSync, existsSync, mkdirSync, openSync, writeSync } from 'node:fs';
d972af76 4import { dirname } from 'node:path';
8114d10e 5
c1565026 6import { Storage } from './Storage';
7b5dbe91 7import { BaseError } from '../../exception';
268a74bb 8import { FileType, type Statistics } from '../../types';
9bf0ef23
JB
9import {
10 AsyncLock,
11 AsyncLockType,
12 Constants,
13 JSONStringifyWithMapSupport,
14 handleFileException,
15 isNullOrUndefined,
16} from '../../utils';
72f041bd 17
100a5301 18export class JsonFileStorage extends Storage {
f1c729e0
JB
19 private static readonly performanceRecords: Map<string, Statistics> = new Map<
20 string,
21 Statistics
22 >();
23
24 private fd?: number;
2a370053 25
1f5df42a
JB
26 constructor(storageUri: string, logPrefix: string) {
27 super(storageUri, logPrefix);
28 this.dbName = this.storageUri.pathname;
72f041bd
JB
29 }
30
31 public storePerformanceStatistics(performanceStatistics: Statistics): void {
2a370053 32 this.checkPerformanceRecordsFile();
dd485b56 33 AsyncLock.acquire(AsyncLockType.performance)
1227a6f1 34 .then(() => {
f1c729e0
JB
35 JsonFileStorage.performanceRecords.set(performanceStatistics.id, performanceStatistics);
36 writeSync(
37 this.fd!,
38 JSONStringifyWithMapSupport([...JsonFileStorage.performanceRecords.values()], 2),
39 0,
40 'utf8',
41 );
1227a6f1
JB
42 })
43 .catch((error) => {
fa5995d6 44 handleFileException(
1227a6f1
JB
45 this.dbName,
46 FileType.PerformanceRecords,
47 error as NodeJS.ErrnoException,
5edd8ba0 48 this.logPrefix,
1227a6f1 49 );
c63c21bc 50 })
1227a6f1 51 .finally(() => {
dd485b56 52 AsyncLock.release(AsyncLockType.performance).catch(Constants.EMPTY_FUNCTION);
1227a6f1 53 });
72f041bd 54 }
b652b0c3 55
2a370053 56 public open(): void {
b652b0c3 57 try {
9bf0ef23 58 if (isNullOrUndefined(this?.fd)) {
d972af76
JB
59 if (!existsSync(dirname(this.dbName))) {
60 mkdirSync(dirname(this.dbName), { recursive: true });
f682b2dc 61 }
f1c729e0 62 this.fd = openSync(this.dbName, 'w+');
a6ceb16a 63 }
b652b0c3 64 } catch (error) {
fa5995d6 65 handleFileException(
e7aeea18 66 this.dbName,
7164966d
JB
67 FileType.PerformanceRecords,
68 error as NodeJS.ErrnoException,
5edd8ba0 69 this.logPrefix,
e7aeea18 70 );
2a370053
JB
71 }
72 }
73
74 public close(): void {
75 try {
a6ceb16a 76 if (this?.fd) {
d972af76 77 closeSync(this.fd);
f1c729e0 78 delete this?.fd;
2a370053
JB
79 }
80 } catch (error) {
fa5995d6 81 handleFileException(
e7aeea18 82 this.dbName,
7164966d
JB
83 FileType.PerformanceRecords,
84 error as NodeJS.ErrnoException,
5edd8ba0 85 this.logPrefix,
e7aeea18 86 );
2a370053
JB
87 }
88 }
89
90 private checkPerformanceRecordsFile(): void {
73d09045 91 if (!this?.fd) {
7b5dbe91 92 throw new BaseError(
5edd8ba0 93 `${this.logPrefix} Performance records '${this.dbName}' file descriptor not found`,
e7aeea18 94 );
b652b0c3
JB
95 }
96 }
72f041bd 97}