@digigov-oss/gsis-audit-record-db
Version:
JSON file storage database for use with audit mechanism of GSIS
95 lines (94 loc) • 2.67 kB
JavaScript
import fs from 'fs';
const LOCK_FILE_PATH = "/tmp/sequence";
const SEQUENCE_FILE = "/tmp/sequence";
/**
* timeout for lock file, we will try to delete it after timeout, in case was not deleted on previous run
* you can increase this value if you have a lot of processes running on the same machine
* @type {number}
* @env TIMEOUT_LOCK_FILE
*/
const TIMEOUT_LOCK_FILE = (process.env.TIMEOUT_LOCK_FILE ? ~~process.env.TIMEOUT_LOCK_FILE : undefined) || 10000;
/**
* set delay in ms
* @param ms
* @returns Promise<void>
*/
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
/**
* create a lock file
* @param path
* @param timeout
* @returns Promise<number>
*/
const lockFile = async (path, timeout = 0) => {
//TODO if the file exists for long time have to delete it
// because probably something is broken on previous run
// this works but may be not the best solution
if (timeout++ > TIMEOUT_LOCK_FILE) {
console.log(timeout, " times loop, try to unlock");
await delay(1000);
unlockFile(path);
}
;
const lockPath = `${path}.lock`;
try {
return fs.openSync(lockPath, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_RDWR);
}
catch (error) {
const err = error;
if (err.code !== "EEXIST")
console.log(err.message);
return lockFile(path, timeout);
}
};
/**
* unlink the lock file
* @param path
* @param timeout
* @returns Promise<void>
*/
const unlockFile = async (path, timeout = 0) => {
const lockPath = `${path}.lock`;
if (timeout++ > TIMEOUT_LOCK_FILE) {
console.log(timeout, " times loop, unlock exit");
return;
}
;
try {
return fs.unlinkSync(lockPath);
}
catch (error) {
const err = error;
if (err.code === "ENOENT") {
return;
}
else {
console.log(err.message);
await delay(500);
return unlockFile(path, timeout++);
}
}
};
/**
* update the sequence number on giveb sequence file
* @param seqfile
* @param lockfile
* @returns number
*/
const sequence = (seqfile = "", lockfile = "") => {
let SEQF = SEQUENCE_FILE;
let LFP = LOCK_FILE_PATH;
if (seqfile !== "")
SEQF = seqfile;
if (lockfile !== "")
LFP = lockfile;
if (!fs.existsSync(SEQF)) {
fs.writeFileSync(SEQF, "0");
}
const abla = lockFile(LFP);
let seq = ~~fs.readFileSync(SEQF); //Read as integer ~~ is synonimus for parseInt
fs.writeFileSync(SEQF, "" + ++seq);
const oubla = unlockFile(LFP);
return seq;
};
export default sequence;