mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(gateway): align dedupe eviction with entry timestamp
This commit is contained in:
committed by
Peter Steinberger
parent
11e6c66004
commit
da03269f6d
@@ -1,6 +1,7 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import type { HealthSummary } from "../commands/health.js";
|
||||
import type { ChatAbortControllerEntry } from "./chat-abort.js";
|
||||
import { DEDUPE_MAX } from "./server-constants.js";
|
||||
|
||||
const cleanOldMediaMock = vi.fn(async () => {});
|
||||
|
||||
@@ -222,4 +223,31 @@ describe("startGatewayMaintenanceTimers", () => {
|
||||
|
||||
stopMaintenanceTimers(timers);
|
||||
});
|
||||
|
||||
it("evicts dedupe overflow by oldest timestamp even after reinsertion", async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-03-22T00:00:00Z"));
|
||||
const { startGatewayMaintenanceTimers } = await import("./server-maintenance.js");
|
||||
const deps = createMaintenanceTimerDeps();
|
||||
const now = Date.now();
|
||||
|
||||
for (let index = 0; index < DEDUPE_MAX; index += 1) {
|
||||
deps.dedupe.set(`stable-${index}`, { ts: now - 1_000 + index, ok: true });
|
||||
}
|
||||
|
||||
deps.dedupe.delete("stable-10");
|
||||
deps.dedupe.set("stable-10", { ts: now - 2_000, ok: true });
|
||||
deps.dedupe.set("overflow-newest", { ts: now - 100, ok: true });
|
||||
|
||||
const timers = startGatewayMaintenanceTimers(deps);
|
||||
|
||||
await vi.advanceTimersByTimeAsync(60_000);
|
||||
|
||||
expect(deps.dedupe.size).toBe(DEDUPE_MAX);
|
||||
expect(deps.dedupe.has("stable-10")).toBe(false);
|
||||
expect(deps.dedupe.has("stable-0")).toBe(true);
|
||||
expect(deps.dedupe.has("overflow-newest")).toBe(true);
|
||||
|
||||
stopMaintenanceTimers(timers);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -90,9 +90,15 @@ export function startGatewayMaintenanceTimers(params: {
|
||||
}
|
||||
}
|
||||
if (params.dedupe.size > DEDUPE_MAX) {
|
||||
const entries = [...params.dedupe.entries()].toSorted((a, b) => a[1].ts - b[1].ts);
|
||||
for (let i = 0; i < params.dedupe.size - DEDUPE_MAX; i++) {
|
||||
params.dedupe.delete(entries[i][0]);
|
||||
const excess = params.dedupe.size - DEDUPE_MAX;
|
||||
// Keep overflow eviction aligned with the entry timestamp, not Map
|
||||
// insertion order, so refresh/reinsert paths still prune the oldest data.
|
||||
const oldestKeys = [...params.dedupe.entries()]
|
||||
.toSorted(([, left], [, right]) => left.ts - right.ts)
|
||||
.slice(0, excess)
|
||||
.map(([key]) => key);
|
||||
for (const key of oldestKeys) {
|
||||
params.dedupe.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user