sessions: reclaim orphan self-pid lock files

This commit is contained in:
bmendonca3
2026-03-02 12:20:03 -07:00
committed by Peter Steinberger
parent 160dad56c4
commit 4985c561df
2 changed files with 71 additions and 11 deletions

View File

@@ -300,13 +300,13 @@ describe("acquireSessionWriteLock", () => {
}
});
it("does not reclaim lock files without starttime (backward compat)", async () => {
it("reclaims orphan lock files without starttime when PID matches current process", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-lock-"));
try {
const sessionFile = path.join(root, "sessions.json");
const lockPath = `${sessionFile}.lock`;
// Old-format lock without starttime — should NOT be reclaimed just because
// starttime is missing. The PID is alive, so the lock is valid.
// Simulate an old-format lock file left behind by a previous process
// instance that reused the same PID (common in containers).
await fs.writeFile(
lockPath,
JSON.stringify({
@@ -316,19 +316,46 @@ describe("acquireSessionWriteLock", () => {
"utf8",
);
await expect(acquireSessionWriteLock({ sessionFile, timeoutMs: 50 })).rejects.toThrow(
/session file locked/,
);
await expectCurrentPidOwnsLock({ sessionFile, timeoutMs: 500 });
} finally {
await fs.rm(root, { recursive: true, force: true });
}
});
it("does not treat malformed starttime as recycled", async () => {
it("does not reclaim active in-process lock files without starttime", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-lock-"));
try {
const sessionFile = path.join(root, "sessions.json");
const lockPath = `${sessionFile}.lock`;
const lock = await acquireSessionWriteLock({ sessionFile, timeoutMs: 500 });
await fs.writeFile(
lockPath,
JSON.stringify({
pid: process.pid,
createdAt: new Date().toISOString(),
}),
"utf8",
);
await expect(
acquireSessionWriteLock({
sessionFile,
timeoutMs: 50,
allowReentrant: false,
}),
).rejects.toThrow(/session file locked/);
await lock.release();
} finally {
await fs.rm(root, { recursive: true, force: true });
}
});
it("does not reclaim active in-process lock files with malformed starttime", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-lock-"));
try {
const sessionFile = path.join(root, "sessions.json");
const lockPath = `${sessionFile}.lock`;
const lock = await acquireSessionWriteLock({ sessionFile, timeoutMs: 500 });
await fs.writeFile(
lockPath,
JSON.stringify({
@@ -339,9 +366,14 @@ describe("acquireSessionWriteLock", () => {
"utf8",
);
await expect(acquireSessionWriteLock({ sessionFile, timeoutMs: 50 })).rejects.toThrow(
/session file locked/,
);
await expect(
acquireSessionWriteLock({
sessionFile,
timeoutMs: 50,
allowReentrant: false,
}),
).rejects.toThrow(/session file locked/);
await lock.release();
} finally {
await fs.rm(root, { recursive: true, force: true });
}