piker/ai/prompt-io/opencode/20261028T160846Z_7242dcb9_w...

78 lines
3.1 KiB
Markdown
Raw Normal View History

.data: reconnect after websocket reader close errors A Binance Ping racing local socket closure makes trio-websocket's reader send a Pong while wsproto is LOCAL_CLOSING. That reader nursery error escapes proxy_msgs(), then tears down brokerd and pikerd instead of restoring quote delivery. Classify NoBsWs.recon_errors around the entire websocket context, with collapse_eg() outside it so a singleton reader exit group reaches the reconnect handler. Invalidate the stale connected event and socket reference before retrying. Keep retry sleep unshielded so parent cancellation stops recovery promptly. Deats, - Add real loopback websocket coverage: TCP, handshake, Ping, reader dispatch and wsproto's actual Pong validation. - Control only the first client Ping's protocol-state ordering, withholding its Close frame to prevent a peer response racing the deterministic LOCAL_CLOSING reproducer. - Require fresh data on a replacement connection, plus exactly one connection when cancelling at the reader or retry boundary. - Use RuntimeError for the unexpected-failure control: LocalProtocolError is now a recoverable connection failure. - Preserve the original unexpected exception with bare raise, and assert its identity in the test. Log recoverable errors with the websocket URL and the underlying traceback. This is a local follow-up, not another downstream cherry-pick. The earlier wrapper suppressed escaped communication failures; 97eb8347 deliberately re-raised them. Retain that outer error visibility rather than restoring suppression without recovery. The isolated baseline reproduces the live Pong failure; all 13 selected Binance/websocket cases pass with this fix. Human live qualification remains separate from these loopback regressions. Follow-up-to: 97eb834799cd8922d4efb96f442201291281c08a Original-equivalent: d50ab6124cd0e1646c82fa4a85d7c13bfff82611 Related-history: 3d83b61f3f7b982e84a4230dba5777f1407c78f1 Prompt-IO: ai/prompt-io/opencode/20261028T160846Z_7242dcb9_websocket_close.md (this patch was generated in some part by `opencode` using `gpt-6.1-sol` (`openai`))
2026-10-28 16:48:06 +00:00
---
created_at: 2026-10-28T16:08:46Z
generated_by:
harness: opencode
provider: openai
model: openai/gpt-6.1-sol
git_ref: 7242dcb9
scope: code
substantive: true
raw_file: 20261028T160846Z_7242dcb9_websocket_close.raw.md
---
## Prompt
The human reported repeated live Binance perp crashes after correct
worktree startup: the real trio-websocket reader attempted a Pong
while wsproto was LOCAL_CLOSING. They asked whether an existing
downstream websocket fix should be reused, then requested:
> ok add the fix now, follow by a /commit-plan and then i'll test
> before saving it ya?
They approved a real websocket reader/close regression covering
recovery and intentional shutdown, and separately authorized
reconciling this worktree's legacy workflow bookkeeping while
preserving existing archives.
## Response summary
The older `3d83b61f3f7b982e84a4230dba5777f1407c78f1` wrapper
suppressed escaped communication failures. The landing replay
`97eb8347` of `d50ab6124cd0e1646c82fa4a85d7c13bfff82611`
added propagation; it did not restart a reader-context failure.
Existing `LocalProtocolError` membership in NoBsWs.recon_errors
only protected the receive relay, not reader-nursery context exit.
Classify these errors around the complete websocket context and
retry instead of restoring outer suppression. Place collapse_eg
outside that context, invalidate stale connection readiness and
socket references, and leave the retry wait cancellable. Preserve
unexpected failures and mixed exception groups for propagation.
After review, use RuntimeError rather than ValueError for the
test-only unexpected-failure sentinel. Its injected exception has
no underlying cause. Production recovery logs retain the original
traceback and now name the URL; unexpected exceptions use bare
raise to preserve identity, existing causes and notes.
The deterministic seam controls protocol-state ordering in the real
client Ping handler. It does not replace the websocket transport,
reader, context manager, reconnect task or wsproto exception.
## Files changed
- `piker/data/_web_bs.py`: reader-context failure recovery.
- `tests/test_websocket.py`: loopback recovery and two shutdown
variants; retain unexpected-failure propagation control.
- This provenance pair: live report, lineage and test scope.
## Verification
Baseline uses new tests against original HEAD websocket code in an
isolated exact-tree checkout. The recovery case fails with the
reported Pong-in-LOCAL_CLOSING LocalProtocolError.
Fixed code passes 13 cases across tests/test_websocket.py and
tests/test_binance.py. Exact-boundary verification and native-library
configuration are retained in the ignored commit-plan package.
Live testing remains human-owned and pending.
## Human edits
No direct manual source edits observed in this follow-up. The human
supplied live failures, corrected the earlier daemon/worktree setup,
set the narrow landing scope, requested source-fix reuse, and will
test before reviewing and committing. Existing commits are retained.
The human requested the RuntimeError sentinel and preservation of
underlying error context. The raw partner retains the initial output.