The `proxy_msgs()` deadline covers both `ws.get_message()` and
`snd.send()`. Repeated socket-ready reports with no first relay
could therefore mean either a silent source or a blocked local
consumer; the old generic reset log could not distinguish them.
Track the currently awaited operation and report its phase, URL,
deadline, accumulated timeout count and reset threshold on each
timeout. Snapshot `NoBsWs._timeout` once per iteration so the log
reflects the deadline that actually elapsed. Keep the existing
shared deadline, counter behavior and reconnect policy intact.
Add two real loopback regressions: a silent websocket server and
one payload blocked on an unconsumed zero-capacity Trio relay.
Require the matching timeout phase and URL before the reset budget
is exhausted. The 15 selected Binance/websocket cases pass.
The human observes this after invalid `.usdm.` startup followed
by corrected `.usdtm.` input. Metadata accepts the typo but later
history lookup expects canonical keys. Record that investigation
as context; this diagnostic patch does not fix FQME validation,
failed-startup cleanup or prove the cause of corrected-feed stalls.
Prompt-IO: ai/prompt-io/opencode/20261028T180856Z_032580bf_timeout_phase.md
(this patch was generated in some part by `opencode` using
`gpt-6.1-sol` (`openai`))
An INFO pikerd still hid websocket connection-success messages.
The shared ._util.log emitter is piker.data, but open_feed_bus()
configured piker.data.feed. Errors reached bare stderr while
INFO diagnostics remained disabled on the actual emitter.
Configure the shared logger by its exact log.name and prefer
the actor's loglevel over a quieter per-client request for these
actor-wide transport diagnostics. Preserve the selected client
level passed to provider feed startup.
Also,
- retain the existing handshake-success report and add URL-tagged
readiness after fixture setup and first-message relay once per
connection, including replacement sockets.
- include the URL in receive-timeout reset errors so Binance's
independent bookTicker and aggTrade routes are distinguishable.
- prove real console INFO visibility through production feed
startup, stopping before provider lookup, then restore logging
state; the original code fails with the emitter at WARNING.
- extend the loopback recovery test to verify both readiness
reports and the first relay from the replacement connection.
First-message relay is raw websocket traffic, not proof that
parsed market data or chart updates have recovered. The 18
logging/Binance/websocket cases pass; live reporting qualification
remains separate.
This is a local follow-up, not a downstream cherry-pick. The
54da2973 websocket cleanup and 5adf77a9 namespace fix do not
configure this shared emitter. Relevant local histories and
dirty IB-history/TIPC deltas contain no equivalent wiring fix.
Prompt-IO: ai/prompt-io/opencode/20261028T165638Z_b95e7c79_reconnect_logging.md
(this patch was generated in some part by `opencode` using
`gpt-6.1-sol` (`openai`))
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: 97eb834799
Original-equivalent: d50ab6124c
Related-history: 3d83b61f3f
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`))
- restart handled handshake failures before touching cancel state
- propagate `trio.Cancelled` without shielded retry throttling
- bound initial connection waits and expose transport failures
- cover real reconnect task paths in `test_websocket.py`
Prompt-IO: ai/prompt-io/opencode/20260901T024235Z_e09e306a_prompt_io.md
(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))