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