fix: prune terminal acpx process leases

This commit is contained in:
Peter Steinberger
2026-05-18 04:07:38 +01:00
parent b15ab1f914
commit d4ca46545c
2 changed files with 24 additions and 2 deletions

View File

@@ -41,6 +41,23 @@ describe("createAcpxProcessLeaseStore", () => {
);
});
});
it("deletes terminal leases so long-running gateways do not hit the plugin state cap", async () => {
await withOpenClawTestState({ label: "acpx-leases-terminal-prune" }, async () => {
const store = createAcpxProcessLeaseStore();
for (let index = 0; index < 1050; index += 1) {
await store.save(makeLease(index));
await store.markState(`lease-${index}`, "closed");
}
await store.save(makeLease(1051));
expect(await store.load("lease-0")).toBeUndefined();
expect((await store.listOpen("gateway-test")).map((lease) => lease.leaseId)).toEqual([
"lease-1051",
]);
});
});
});
describe("withAcpxLeaseEnvironment", () => {

View File

@@ -35,12 +35,17 @@ type LeaseStoreEntry = {
const ACPX_PLUGIN_ID = "acpx";
const PROCESS_LEASES_NAMESPACE = "process-leases";
const PROCESS_LEASES_MAX_ENTRIES = 900;
const leaseStore = createPluginStateKeyedStore<LeaseStoreEntry>(ACPX_PLUGIN_ID, {
namespace: PROCESS_LEASES_NAMESPACE,
maxEntries: 10_000,
maxEntries: PROCESS_LEASES_MAX_ENTRIES,
});
function isTerminalLeaseState(state: AcpxProcessLeaseState): boolean {
return state === "closed" || state === "lost";
}
function normalizeLease(value: unknown): AcpxProcessLease | undefined {
if (typeof value !== "object" || value === null) {
return undefined;
@@ -88,7 +93,7 @@ export function createAcpxProcessLeaseStore(): AcpxProcessLeaseStore {
): Promise<void> {
const run = updateQueue.then(async () => {
const current = await readStoredLeases();
const next = mutator(current);
const next = mutator(current).filter((lease) => !isTerminalLeaseState(lease.state));
const nextIds = new Set(next.map((lease) => lease.leaseId));
await Promise.all([
...current