Files
proxy_tmdb/lib/lockFile.js

61 lines
1.6 KiB
JavaScript

// Simple PID-based lock file. Atomic via O_EXCL.
// If a stale lock is found (PID no longer alive), it is removed.
import { closeSync, openSync, readFileSync, unlinkSync, writeSync } from 'node:fs';
function isAlive(pid) {
try {
process.kill(pid, 0);
return true;
} catch (e) {
return e.code === 'EPERM';
}
}
export function acquireLock(lockPath) {
for (let attempt = 0; attempt < 2; attempt++) {
try {
const fd = openSync(lockPath, 'wx');
writeSync(fd, String(process.pid));
closeSync(fd);
const release = () => {
try {
unlinkSync(lockPath);
} catch {
/* ignore */
}
};
process.on('exit', release);
process.on('SIGINT', () => {
release();
process.exit(130);
});
process.on('SIGTERM', () => {
release();
process.exit(143);
});
return release;
} catch (err) {
if (err.code !== 'EEXIST') throw err;
// Lock exists — check if owner is still alive
let pid = 0;
try {
pid = parseInt(readFileSync(lockPath, 'utf8').trim(), 10);
} catch {
/* unreadable */
}
if (pid && isAlive(pid)) {
throw new Error(`Cron already running (PID ${pid}, lock ${lockPath})`);
}
// Stale lock — remove and retry
console.log(`Removing stale lock (PID ${pid || '?'} no longer alive): ${lockPath}`);
try {
unlinkSync(lockPath);
} catch {
/* ignore */
}
}
}
throw new Error(`Could not acquire lock after retries: ${lockPath}`);
}