openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
50 lines (49 loc) • 1.86 kB
JavaScript
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { t as getFileLockProcessStartTime } from "./pid-alive-XuW58Ofz.js";
import { t as isLockOwnerDefinitelyStale } from "./stale-lock-file-B5kcl7Ks.js";
import { t as acquireFileLockSync } from "./file-lock-manager-Cqz0dyf7.js";
import fs from "node:fs";
//#region src/infra/file-lock-sync.ts
/** Synchronous lock for legacy stores that cannot transact in SQLite yet. */
function acquireFileLockSyncWithRetry(path) {
rejectUnsupportedLockPath(`${path}.lock`);
const processStartTime = getFileLockProcessStartTime(process.pid);
const createPayload = () => ({
pid: process.pid,
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
...processStartTime === null ? {} : { starttime: processStartTime }
});
const isStale = ({ payload }) => isLockOwnerDefinitelyStale({ payload: isRecord(payload) ? payload : null });
const lock = acquireFileLockSync(path, {
staleMs: 3e4,
retry: {
retries: 9,
factor: 1,
minTimeout: 20,
maxTimeout: 20,
randomize: false
},
staleRecovery: "remove-if-unchanged",
payload: createPayload,
shouldReclaim: isStale,
shouldRemoveStaleLock: isStale
});
return () => lock.release();
}
function rejectUnsupportedLockPath(lockPath) {
let observed;
try {
observed = fs.lstatSync(lockPath);
} catch (error) {
if (error.code === "ENOENT") return;
throw error;
}
if (observed.isFile() && !observed.isSymbolicLink()) return;
if (!observed.isDirectory() || observed.isSymbolicLink()) throw new Error(`Storage lock path has an unsupported legacy type: ${lockPath}`);
throw Object.assign(/* @__PURE__ */ new Error(`Legacy storage lock requires manual removal after verifying no older OpenClaw process is running: ${lockPath}`), {
code: "file_lock_stale",
lockPath
});
}
//#endregion
export { acquireFileLockSyncWithRetry as t };