Open
Description
What happens
Attaching to a large session sometimes takes about 100 seconds. The history arrives in chunks: the first chunks land in tens of milliseconds, then the client waits about 100 s for the last one.
Why it matters
The session looks empty or frozen to the person attaching (web UI, TUI) for over a minute and a half. It hits large sessions, which are the ones people come back to.
What was seen
During the audits for #457 (lazy session loading), the measurement auditor saw it on main (aed1afb) as well as on the branch, so the branch didn't cause it:
- An attach to a 5.7 MB / 23 MB session took about 101 s in 2 of 7 benchmark runs.
- On
main: chunks f0 to f4 arrived within 80 ms, and the final 218 KB chunk arrived at 101,929 ms. - The final chunk waited on the socket's
draincallback, which didn't fire. Something else released it about 100 s later.
What we want
An attach replay finishes as soon as the client can take the data, and never waits on a drain that doesn't come. If the socket is genuinely stuck, the replay should fail visibly rather than stall.
🤖 Implementation context (for agents / maintainers)
- Where:
src/daemon/server.tsaround the chunked replayflush(≈ lines 987-997 onaed1afb), which awaits the socket'sdrainbefore sending the next chunk. - Likely cause: Bun's
ServerWebSocket.sendbackpressure status vs. whendrainfires. If the lastsendreturned a backpressure status but the buffer emptied without adrainevent (or the wait was armed after it fired), the await only ends when something else (a timeout, the next frame) unblocks it. The ~100 s may match an idle or ping timeout. - Reproduction: the auditor's
stall.ts(per-frame timing of an attach) against a daemon holding sessions with multi-MB transcripts; repeat attaches until one stalls. - Fix direction: re-check
getBufferedAmount()on a short timer instead of relying only ondrain, or arm the wait before checking the send status; bound the wait and close the socket with a clear code if it never drains.
Metadata
Metadata
Assignees
Labels
No labels
Activity