Files
Gambling_API/lib/database-lock.js
T
2026-09-09 10:55:40 +02:00

21 lines
1.2 KiB
JavaScript

const crypto = require('node:crypto');
// Claim ownership inside a SQLite transaction, including replacement of a dead PID.
// This avoids races between two processes attempting crash recovery at once.
async function acquireDatabaseLock(db) {
const token = crypto.randomUUID();
await db.exec('BEGIN IMMEDIATE');
try {
await db.exec('CREATE TABLE IF NOT EXISTS runtime_owner (id INTEGER PRIMARY KEY CHECK(id = 1), pid INTEGER NOT NULL, token TEXT NOT NULL)');
const owner = await db.get('SELECT pid FROM runtime_owner WHERE id = 1');
if (owner) {
if (!Number.isInteger(owner.pid) || owner.pid <= 0) throw new Error('Invalid database owner');
try {process.kill(owner.pid, 0); throw new Error(`Database is in use by process ${owner.pid}`);}
catch (error) {if (error.code !== 'ESRCH') throw error;}
}
await db.run('INSERT INTO runtime_owner(id,pid,token) VALUES(1,?,?) ON CONFLICT(id) DO UPDATE SET pid=excluded.pid,token=excluded.token', process.pid, token);
await db.exec('COMMIT');
} catch (error) {await db.exec('ROLLBACK'); throw error;}
return () => db.run('DELETE FROM runtime_owner WHERE id = 1 AND token = ?', token);
}
module.exports = {acquireDatabaseLock};