UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

74 lines (73 loc) • 3.52 kB
import { a as resolveGlobalSingleton } from "./global-singleton-0m-JziJW.mjs"; import { u as readDatabasePathIdentitySync } from "./sqlite-worker-identity-KSR14F6C.mjs"; import { c as resolveOpenClawAgentSqlitePath } from "./openclaw-agent-db.paths-DVbbFaej.mjs"; import { n as isActiveStoreWriter, r as runQueuedStoreWrite } from "./store-writer-queue-Cq6rziq_.mjs"; //#region src/state/openclaw-agent-write-admission.ts const admission = resolveGlobalSingleton(Symbol.for("openclaw.agentDatabaseWriteAdmission"), () => ({ queues: /* @__PURE__ */ new Map(), workers: /* @__PURE__ */ new Map() })); const SQLITE_SESSION_WRITER_QUEUES = admission.queues; function runOpenClawAgentWriteAdmission(options, run, reentrant = false, timing, signal) { const pathname = resolveOpenClawAgentSqlitePath(options); const identity = readDatabasePathIdentitySync(pathname); const storePath = identity.canonicalPath; const assertCurrent = () => { const current = readDatabasePathIdentitySync(pathname); if (current.canonicalPath !== storePath || identity.key.startsWith("file:") && (current.key !== identity.key || current.birthtime !== identity.birthtime)) throw new Error("Agent database target changed before write admission"); }; return runQueuedStoreWrite({ queues: admission.queues, storePath, label: "agent database write admission", reentrant: reentrant && !admission.workers.has(storePath), fn: async () => { assertCurrent(); return await run(identity, assertCurrent); }, timing, signal }); } /** Reserve a native write permit without admitting inherited foreground callbacks. */ function runOpenClawAgentWorkerWrite(options, run, timing, signal) { if ("target" in options) { const { handle, incarnation } = options.target; return runQueuedStoreWrite({ queues: admission.queues, storePath: `ephemeral:${handle}:${incarnation}`, label: "incognito agent database write admission", reentrant: false, fn: async () => { options.assertCurrent(); return run(); }, timing, signal }); } return runOpenClawAgentWriteAdmission(options, async ({ canonicalPath: storePath }) => { const owner = {}; admission.workers.set(storePath, owner); try { return await run(); } finally { if (admission.workers.get(storePath) === owner) admission.workers.delete(storePath); } }, true, timing, signal); } /** Compose the existing foreground queues without inverting inherited acquisition order. */ async function runOpenClawAgentWriteAdmissions(options, run) { const selected = new Map(options.map((option) => [resolveOpenClawAgentSqlitePath(option), option])); const paths = [...selected.keys()].toSorted(); const inherited = [...admission.queues.keys()].filter((pathname) => isActiveStoreWriter(admission.queues, pathname)); if (paths.some((pathname) => inherited.includes(pathname))) throw new Error("Session read batch cannot reenter an active SQLite writer admission"); if (paths.some((pathname) => inherited.some((held) => held > pathname))) throw new Error("Session read batch would invert inherited SQLite writer admission order"); const acquire = (index) => { const pathname = paths[index]; return pathname === void 0 ? Promise.resolve().then(run) : runOpenClawAgentWriteAdmission(selected.get(pathname), () => acquire(index + 1), true); }; return await acquire(0); } //#endregion export { runOpenClawAgentWriteAdmissions as i, runOpenClawAgentWorkerWrite as n, runOpenClawAgentWriteAdmission as r, SQLITE_SESSION_WRITER_QUEUES as t };