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