From 35fc2a11209a101457a521367d1bf01b789dd127 Mon Sep 17 00:00:00 2001 From: Sash Zats Date: Sun, 25 Jan 2026 21:35:26 +0000 Subject: [PATCH] fix: release session locks on process termination Adds cleanup handlers to release held file locks when the process terminates via SIGTERM, SIGINT, or normal exit. This prevents orphaned lock files that would block future sessions. Fixes #1951 --- src/agents/session-write-lock.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) 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 {