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