@digigov-oss/gsis-audit-record-db
Version:
JSON file storage database for use with audit mechanism of GSIS
109 lines (108 loc) • 3.76 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("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 = (path, timeout = 0) => __awaiter(void 0, void 0, void 0, function* () {
//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");
yield delay(1000);
unlockFile(path);
}
;
const lockPath = `${path}.lock`;
try {
return fs_1.default.openSync(lockPath, fs_1.default.constants.O_CREAT | fs_1.default.constants.O_EXCL | fs_1.default.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 = (path, timeout = 0) => __awaiter(void 0, void 0, void 0, function* () {
const lockPath = `${path}.lock`;
if (timeout++ > TIMEOUT_LOCK_FILE) {
console.log(timeout, " times loop, unlock exit");
return;
}
;
try {
return fs_1.default.unlinkSync(lockPath);
}
catch (error) {
const err = error;
if (err.code === "ENOENT") {
return;
}
else {
console.log(err.message);
yield 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_1.default.existsSync(SEQF)) {
fs_1.default.writeFileSync(SEQF, "0");
}
const abla = lockFile(LFP);
let seq = ~~fs_1.default.readFileSync(SEQF); //Read as integer ~~ is synonimus for parseInt
fs_1.default.writeFileSync(SEQF, "" + ++seq);
const oubla = unlockFile(LFP);
return seq;
};
exports.default = sequence;