Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion apps/hub/src/live-app/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,11 @@ export function createLiveAppProxy(options: {
if (!(await allows(request, entry)))
return new Response(liveAppWording.signIn, { status: 401 });
entry.lastUsed = Date.now();
if (request.headers.get("upgrade")?.toLowerCase() !== "websocket")
if (request.headers.get("upgrade")?.toLowerCase() !== "websocket") {
// The app decides how long a response may stay quiet, not Bun's 10-second default.
server.timeout(request, 0);
return forward(request, entry);
}
const url = new URL(request.url);
const socketUrl = new URL(url.pathname + url.search, entry.target);
socketUrl.protocol = "ws:";
Expand Down
2 changes: 2 additions & 0 deletions apps/hub/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ if (import.meta.main) {
const server = Bun.serve({
hostname: runtime.hostname,
port: runtime.port,
// Bun's 10-second default drops slow routes; the run stream's 5-second heartbeat stays well inside this.
idleTimeout: 120,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 · 120s idle timeout still drops hub routes that can stay silent for up to 300s

Bun closes a connection after idleTimeout seconds with no bytes sent. This hub serves POST /api/tenants/:t/workflows/deployments (the route agent-token-bridge.ts matches), and that route sends nothing until it has installed, probed and gated the source. Per the comment in deploy-tools.ts, those stages can take 120s + 120s + 60s, which is why callers allow DEPLOY_TIMEOUT_MS = 300_000. The web client likewise allows 5 minutes per hub call, coordinator deploys included (HUB_REQUEST_CEILING_MS). The vendored Interchange hub uses idleTimeout: 0 for the same routes. With 120, any deploy whose stages take more than about 2 minutes in total gets its socket reset, while the hub keeps working and finishes the deploy.

A workflow or coordinator deploy where sidecar ensure plus connection take more than 120s, e.g. a slow container start, so no response byte goes out within 120s.

Resolve this comment. Triage will not finish while it is open.

fetch: runtime.app.fetch,
websocket: runtime.websocket,
});
Expand Down