code-yeongyu / code-yeongyu/senpi
Large task.updated bursts overflow the RPC event queue and tear down the connection (observed at 67MB)
- Dominant language
- TypeScript
- Stars
- 429
- Forks
- 98
- Avg merge
- 5h 3m
- Merged PRs (30d)
- 526
Description
## Summary
A large `task.updated` event burst overflows the RPC connection's event queue, and the transport is torn down — disconnecting a live session mid-turn. Observed live at **67 MB** in a single burst.
The teardown is by design: `RpcConnectionSink.close()` is documented at `packages/coding-agent/src/modes/rpc/connection-handler.ts:126` as *"Tears the transport down once its event queue can no longer deliver (overflow, write failure)."* So the connection loss is the intended response to overflow — the problem is that a routine payload can reach that condition at all.
## Live observation
- A `task.updated` burst of ~**67 MB** disconnected session `a15d1cb8`.
- There is no visible backpressure or chunking on the producing side, so a large in-flight task simply exceeds what the queue can deliver.
## Why this matters beyond the disconnect
**It is symptomatically identical to an unrelated, recently fixed defect.** Until today this host also suffered an RPC socket-deletion race (an old host unlinking the new host's socket; fixed in senpi#1436 and omo-desktop-app#418). Both produce *"the session lost its connection mid-turn"*.
That made the overflow a genuine misdiagnosis hazard: while chasing the socket race, connection losses caused by payload overflow looked like the same bug. Anyone investigating RPC churn should distinguish them explicitly:
| symptom | socket race (fixed) | queue overflow (this issue) |
|---|---|---|
| trigger | host takeover / reload | one large event burst |
| socket path | unlinked by the predecessor | intact |
| correlates with | epoch churn, reattach failures | payload size |
## Mitigating context
After the deploy carrying senpi#1436 / omo#7899 / omo-desktop-app#418, a recurrence of this overflow was handled gracefully: the turn error surfaced as `omo host restarted mid-turn; the session was resumed` rather than stopping silently, `omo.session.reattached` fired, and spawn failures did not increase. So the reattach path now absorbs it — but the session still loses its connection, and the underlying payload problem is unaddressed.
## Suggested direction
- Bound or chunk large `task.updated` payloads at the producer rather than letting the queue reach an undeliverable state.
- Consider whether an event that cannot be delivered should be truncated/summarised instead of taking the transport down with it — losing one oversized update is strictly better than losing the connection.
- Whatever the fix, keep the clear surfaced error introduced by the reattach work; silent loss was the worse failure and it is already gone.
## Provenance
Live occurrence and the graceful-handling observation reported by the lane that fixed the socket race. The `connection-handler.ts:126` contract quoted above was verified directly against `main`. The exact queue-size constant was not located when filing.
Contributor guide
Research direction
Start at packages/coding-agent/src/modes/rpc/connection-handler.ts:126 and trace the RPC event queue and the producer of task.updated events; the issue notes that the exact queue-size constant was not located. Reproduce or test a large burst, then verify that oversized updates are bounded, chunked, or summarized without tearing down the transport, while the existing surfaced reattach error remains intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend-api-design, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100