27 lines
1.2 KiB
JavaScript
27 lines
1.2 KiB
JavaScript
// tools/secretary-lock.mjs
|
|
// Замок темы поверх proper-lockfile: один воркер на тему. Авто-обновление mtime (update) = пульс,
|
|
// устаревание (stale) = перехват мёртвого. Цель замка — папка _worker внутри темы.
|
|
import lockfile from 'proper-lockfile';
|
|
import { join } from 'node:path';
|
|
|
|
const STALE_MS = Number(process.env.SECRETARY_LOCK_STALE_MS) || 30_000;
|
|
const UPDATE_MS = Number(process.env.SECRETARY_LOCK_UPDATE_MS) || 10_000;
|
|
|
|
function target(workDir) { return join(workDir, '_worker'); }
|
|
|
|
/** Взять замок темы. По умолчанию кидает при занятом (ELOCKED). graceful:true → вернуть null вместо броска. */
|
|
export async function acquireThemeLock(workDir, { graceful = false } = {}) {
|
|
try {
|
|
return await lockfile.lock(target(workDir), { stale: STALE_MS, update: UPDATE_MS, realpath: false });
|
|
} catch (e) {
|
|
if (graceful) return null;
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
/** Занят ли замок темы живым держателем. */
|
|
export async function isThemeLocked(workDir) {
|
|
try { return await lockfile.check(target(workDir), { stale: STALE_MS, realpath: false }); }
|
|
catch { return false; }
|
|
}
|