import Statistics from '../../types/Statistics';
import { Storage } from './Storage';
import fs from 'fs';
+import lockfile from 'proper-lockfile';
export class JSONFileStorage extends Storage {
private fd: number | null = null;
public storePerformanceStatistics(performanceStatistics: Statistics): void {
this.checkPerformanceRecordsFile();
- fs.readFile(this.dbName, 'utf8', (error, data) => {
- if (error) {
- FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error);
- } else {
- const performanceRecords: Statistics[] = data ? JSON.parse(data) as Statistics[] : [];
- performanceRecords.push(performanceStatistics);
- fs.writeFile(this.dbName, JSON.stringify(performanceRecords, null, 2), 'utf8', (err) => {
- if (err) {
- FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, err);
- }
- });
- }
- });
+ lockfile.lock(this.dbName, { stale: 5000, retries: 3 })
+ .then(async (release) => {
+ try {
+ const fileData = fs.readFileSync(this.dbName, 'utf8');
+ const performanceRecords: Statistics[] = fileData ? JSON.parse(fileData) as Statistics[] : [];
+ performanceRecords.push(performanceStatistics);
+ fs.writeFileSync(
+ this.dbName,
+ JSON.stringify(performanceRecords,
+ (key, value) => {
+ if (value instanceof Map) {
+ return {
+ dataType: 'Map',
+ value: [...value]
+ };
+ }
+ return value as Statistics;
+ },
+ 2),
+ 'utf8'
+ );
+ } catch (error) {
+ FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error as NodeJS.ErrnoException);
+ }
+ await release();
+ })
+ .catch(() => { /* This is intentional */ });
}
public open(): void {
this.fd = fs.openSync(this.dbName, 'a+');
}
} catch (error) {
- FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error);
+ FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error as NodeJS.ErrnoException);
}
}
this.fd = null;
}
} catch (error) {
- FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error);
+ FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error as NodeJS.ErrnoException);
}
}