diff --git a/src/agents/session-write-lock.ts b/src/agents/session-write-lock.ts index 54e61d965..bf2a07c9c 100644 --- a/src/agents/session-write-lock.ts +++ b/src/agents/session-write-lock.ts @@ -14,6 +14,32 @@ type HeldLock = { const HELD_LOCKS = new Map(); +/** + * Release all held locks - called on process exit to prevent orphaned locks + */ +async function releaseAllLocks(): Promise { + const locks = Array.from(HELD_LOCKS.values()); + HELD_LOCKS.clear(); + for (const lock of locks) { + try { + await lock.handle.close(); + await fs.rm(lock.lockPath, { force: true }); + } catch { + // Best effort cleanup + } + } +} + +// Register cleanup handlers to release locks on unexpected termination +process.on("exit", releaseAllLocks); +process.on("SIGTERM", () => { + void releaseAllLocks().then(() => process.exit(0)); +}); +process.on("SIGINT", () => { + void releaseAllLocks().then(() => process.exit(0)); +}); +// Note: unhandledRejection handler will call process.exit() which triggers 'exit' + function isAlive(pid: number): boolean { if (!Number.isFinite(pid) || pid <= 0) return false; try {