fix: keep native Workbench SSE alive
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -8,8 +8,10 @@ const kafkaEventBridge = runtime.mode === "agentrun-native" ? startHwlabKafkaEve
|
||||
const app = createWorkbenchHttpApp({ dispatch: runtime.dispatch, snapshot: runtime.application.snapshot?.bind(runtime.application), authorization: process.env.WORKBENCH_API_AUTHORIZATION, mode: runtime.mode, kafkaEventBridge, close: async () => { await kafkaEventBridge?.stop?.(); await runtime.close(); } });
|
||||
const host = process.env.WORKBENCH_API_HOST || "0.0.0.0";
|
||||
const port = positivePort(process.env.WORKBENCH_API_PORT || process.env.PORT, 6677);
|
||||
const server = Bun.serve({ hostname: host, port, fetch: (request) => app.fetch(request) });
|
||||
process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-workbench-api", status: "listening", mode: runtime.mode, host, port: server.port, temporalNamespace: runtime.temporalNamespace, taskQueue: runtime.taskQueue })}\n`);
|
||||
const idleTimeout = positiveInteger(process.env.WORKBENCH_API_IDLE_TIMEOUT_SECONDS, "WORKBENCH_API_IDLE_TIMEOUT_SECONDS");
|
||||
const server = Bun.serve({ hostname: host, port, idleTimeout, fetch: (request) => app.fetch(request) });
|
||||
process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-workbench-api", status: "listening", mode: runtime.mode, host, port: server.port, idleTimeout, temporalNamespace: runtime.temporalNamespace, taskQueue: runtime.taskQueue })}\n`);
|
||||
for (const signal of ["SIGINT", "SIGTERM"] as const) process.once(signal, async () => { server.stop(true); await app.close(); process.exit(0); });
|
||||
|
||||
function positivePort(value: string | undefined, fallback: number) { const parsed = Number.parseInt(String(value ?? fallback), 10); if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) throw new Error("WORKBENCH_API_PORT must be a valid port"); return parsed; }
|
||||
function positiveInteger(value: string | undefined, name: string) { const parsed = Number.parseInt(String(value ?? ""), 10); if (!Number.isSafeInteger(parsed) || parsed < 1) throw new Error(`${name} must be a positive integer`); return parsed; }
|
||||
|
||||
@@ -78,7 +78,10 @@ async function inspectEvents(parsed: Parsed, env: Record<string, string | undefi
|
||||
}
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error?.name !== "AbortError") throw error;
|
||||
const businessCount = frames.filter((entry) => entry.name === "hwlab.event.v1").length;
|
||||
if (error?.name !== "AbortError" && !(error?.code === "ECONNRESET" && businessCount >= minEvents)) {
|
||||
throw codedError("workbench_sse_read_failed", `Workbench SSE read failed: ${error?.code ?? error?.name ?? "unknown"}; frames=${frames.length}; businessEvents=${businessCount}; connected=${frames.some((entry) => entry.name === "workbench.connected")}`);
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user