mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-26 16:41:49 +00:00
fix(test): stabilize windows lock and cache paths
This commit is contained in:
58
src/config/sessions/store.lock.test.ts
Normal file
58
src/config/sessions/store.lock.test.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const acquireSessionWriteLockMock = vi.hoisted(() =>
|
||||
vi.fn(async () => ({ release: vi.fn(async () => {}) })),
|
||||
);
|
||||
|
||||
let withSessionStoreLockForTest: typeof import("./store.js").withSessionStoreLockForTest;
|
||||
let clearSessionStoreCacheForTest: typeof import("./store.js").clearSessionStoreCacheForTest;
|
||||
|
||||
async function loadFreshStoreModule() {
|
||||
vi.resetModules();
|
||||
vi.doMock("../../agents/session-write-lock.js", async (importOriginal) => {
|
||||
const original = await importOriginal<typeof import("../../agents/session-write-lock.js")>();
|
||||
return {
|
||||
...original,
|
||||
acquireSessionWriteLock: acquireSessionWriteLockMock,
|
||||
};
|
||||
});
|
||||
({ withSessionStoreLockForTest, clearSessionStoreCacheForTest } = await import("./store.js"));
|
||||
}
|
||||
|
||||
describe("withSessionStoreLock", () => {
|
||||
beforeEach(async () => {
|
||||
acquireSessionWriteLockMock.mockClear();
|
||||
await loadFreshStoreModule();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
clearSessionStoreCacheForTest();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("derives session lock hold time from the store lock timeout", async () => {
|
||||
await withSessionStoreLockForTest("/tmp/openclaw-store.json", async () => {}, {
|
||||
timeoutMs: 10_000,
|
||||
});
|
||||
|
||||
expect(acquireSessionWriteLockMock).toHaveBeenCalledWith({
|
||||
sessionFile: "/tmp/openclaw-store.json",
|
||||
timeoutMs: 10_000,
|
||||
staleMs: 30_000,
|
||||
maxHoldMs: 15_000,
|
||||
});
|
||||
});
|
||||
|
||||
it("leaves the session lock hold time unset when store locking has no timeout", async () => {
|
||||
await withSessionStoreLockForTest("/tmp/openclaw-store.json", async () => {}, {
|
||||
timeoutMs: 0,
|
||||
});
|
||||
|
||||
expect(acquireSessionWriteLockMock).toHaveBeenCalledWith({
|
||||
sessionFile: "/tmp/openclaw-store.json",
|
||||
timeoutMs: Number.POSITIVE_INFINITY,
|
||||
staleMs: 30_000,
|
||||
maxHoldMs: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,9 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { acquireSessionWriteLock } from "../../agents/session-write-lock.js";
|
||||
import {
|
||||
acquireSessionWriteLock,
|
||||
resolveSessionLockMaxHoldFromTimeout,
|
||||
} from "../../agents/session-write-lock.js";
|
||||
import type { MsgContext } from "../../auto-reply/templating.js";
|
||||
import { writeTextAtomic } from "../../infra/json-files.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
@@ -616,6 +619,9 @@ type SessionStoreLockOptions = {
|
||||
staleMs?: number;
|
||||
};
|
||||
|
||||
const SESSION_STORE_LOCK_MIN_HOLD_MS = 5_000;
|
||||
const SESSION_STORE_LOCK_TIMEOUT_GRACE_MS = 5_000;
|
||||
|
||||
type SessionStoreLockTask = {
|
||||
fn: () => Promise<unknown>;
|
||||
resolve: (value: unknown) => void;
|
||||
@@ -708,6 +714,17 @@ function lockTimeoutError(storePath: string): Error {
|
||||
return new Error(`timeout waiting for session store lock: ${storePath}`);
|
||||
}
|
||||
|
||||
function resolveSessionStoreLockMaxHoldMs(timeoutMs: number | undefined): number | undefined {
|
||||
if (timeoutMs == null || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
||||
return undefined;
|
||||
}
|
||||
return resolveSessionLockMaxHoldFromTimeout({
|
||||
timeoutMs,
|
||||
graceMs: SESSION_STORE_LOCK_TIMEOUT_GRACE_MS,
|
||||
minMs: SESSION_STORE_LOCK_MIN_HOLD_MS,
|
||||
});
|
||||
}
|
||||
|
||||
function getOrCreateLockQueue(storePath: string): SessionStoreLockQueue {
|
||||
const existing = LOCK_QUEUES.get(storePath);
|
||||
if (existing) {
|
||||
@@ -751,6 +768,7 @@ async function drainSessionStoreLockQueue(storePath: string): Promise<void> {
|
||||
sessionFile: storePath,
|
||||
timeoutMs: remainingTimeoutMs,
|
||||
staleMs: task.staleMs,
|
||||
maxHoldMs: resolveSessionStoreLockMaxHoldMs(task.timeoutMs),
|
||||
});
|
||||
result = await task.fn();
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user