Files
PaperClipAI/server/src/services/native-runtime/native-workspace-lock-keepalive.ts
T
DottaandPaperclip aa04c5c2a7 fix(runtime): keep the copyback lock transaction active (#16340)
Keep the dedicated workspace-copyback transaction active with bounded SELECT 1 probes while filesystem work runs. Preserve existing connection, owner-token, takeover and publication fences.

Verified head 7fb0ad45bf: full CI, E2E, Superagent, legacy statuses and Apex 5/5; no unresolved review findings. Real PostgreSQL idle-timeout reproduction and 71 affected cases pass. Strengthened disabled-timeout controls fail when their guard is removed.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-14 17:52:26 -05:00

26 lines
790 B
TypeScript

import { setTimeout } from "node:timers/promises";
import { sql } from "drizzle-orm";
import type { Db } from "@paperclipai/db";
export async function withWorkspaceLockKeepalive<T>(
lock: Pick<Db, "execute">,
idleTimeoutMs: number,
work: () => Promise<T>,
): Promise<T> {
if (!Number.isFinite(idleTimeoutMs) || idleTimeoutMs <= 0) return work();
const stop = new AbortController();
const interval = Math.max(1, Math.min(30_000, Math.floor(idleTimeoutMs / 3)));
const keeper = (async () => {
while (!stop.signal.aborted) {
await setTimeout(interval, undefined, { signal: stop.signal, ref: false });
await lock.execute(sql`select 1`);
}
})().catch(() => undefined);
try {
return await work();
} finally {
stop.abort();
await keeper;
}
}