Commit | Line | Data |
---|---|---|
edd13439 | 1 | // Copyright Jerome Benoit. 2021-2023. All Rights Reserved. |
c27c3eee | 2 | |
130783a7 | 3 | import fs from 'node:fs'; |
8114d10e JB |
4 | |
5 | import lockfile from 'proper-lockfile'; | |
6 | ||
78202038 | 7 | import { Storage } from './Storage'; |
268a74bb JB |
8 | import { FileType, type Statistics } from '../../types'; |
9 | import { FileUtils } from '../../utils/FileUtils'; | |
10 | import { Utils } from '../../utils/Utils'; | |
72f041bd | 11 | |
100a5301 | 12 | export class JsonFileStorage extends Storage { |
2a370053 JB |
13 | private fd: number | null = null; |
14 | ||
1f5df42a JB |
15 | constructor(storageUri: string, logPrefix: string) { |
16 | super(storageUri, logPrefix); | |
17 | this.dbName = this.storageUri.pathname; | |
72f041bd JB |
18 | } |
19 | ||
20 | public storePerformanceStatistics(performanceStatistics: Statistics): void { | |
2a370053 | 21 | this.checkPerformanceRecordsFile(); |
e7aeea18 JB |
22 | lockfile |
23 | .lock(this.dbName, { stale: 5000, retries: 3 }) | |
72092cfc | 24 | .then(async (release) => { |
c63c21bc JB |
25 | try { |
26 | const fileData = fs.readFileSync(this.dbName, 'utf8'); | |
e7aeea18 JB |
27 | const performanceRecords: Statistics[] = fileData |
28 | ? (JSON.parse(fileData) as Statistics[]) | |
29 | : []; | |
c63c21bc | 30 | performanceRecords.push(performanceStatistics); |
1830ad42 JB |
31 | fs.writeFileSync( |
32 | this.dbName, | |
fe791818 | 33 | Utils.JSONStringifyWithMapSupport(performanceRecords, 2), |
1830ad42 JB |
34 | 'utf8' |
35 | ); | |
c63c21bc | 36 | } catch (error) { |
e7aeea18 | 37 | FileUtils.handleFileException( |
e7aeea18 | 38 | this.dbName, |
7164966d JB |
39 | FileType.PerformanceRecords, |
40 | error as NodeJS.ErrnoException, | |
41 | this.logPrefix | |
e7aeea18 | 42 | ); |
c63c21bc JB |
43 | } |
44 | await release(); | |
45 | }) | |
e7aeea18 JB |
46 | .catch(() => { |
47 | /* This is intentional */ | |
48 | }); | |
72f041bd | 49 | } |
b652b0c3 | 50 | |
2a370053 | 51 | public open(): void { |
b652b0c3 | 52 | try { |
b40b5cb3 | 53 | if (this?.fd === undefined || this?.fd === null) { |
a6ceb16a JB |
54 | this.fd = fs.openSync(this.dbName, 'a+'); |
55 | } | |
b652b0c3 | 56 | } catch (error) { |
e7aeea18 | 57 | FileUtils.handleFileException( |
e7aeea18 | 58 | this.dbName, |
7164966d JB |
59 | FileType.PerformanceRecords, |
60 | error as NodeJS.ErrnoException, | |
61 | this.logPrefix | |
e7aeea18 | 62 | ); |
2a370053 JB |
63 | } |
64 | } | |
65 | ||
66 | public close(): void { | |
67 | try { | |
a6ceb16a | 68 | if (this?.fd) { |
2a370053 JB |
69 | fs.closeSync(this.fd); |
70 | this.fd = null; | |
71 | } | |
72 | } catch (error) { | |
e7aeea18 | 73 | FileUtils.handleFileException( |
e7aeea18 | 74 | this.dbName, |
7164966d JB |
75 | FileType.PerformanceRecords, |
76 | error as NodeJS.ErrnoException, | |
77 | this.logPrefix | |
e7aeea18 | 78 | ); |
2a370053 JB |
79 | } |
80 | } | |
81 | ||
82 | private checkPerformanceRecordsFile(): void { | |
73d09045 | 83 | if (!this?.fd) { |
e7aeea18 JB |
84 | throw new Error( |
85 | `${this.logPrefix} Performance records '${this.dbName}' file descriptor not found` | |
86 | ); | |
b652b0c3 JB |
87 | } |
88 | } | |
72f041bd | 89 | } |