diff --git a/quest/m1/README.md b/quest/m1/README.md index e06cb20693..49abe1819c 100644 --- a/quest/m1/README.md +++ b/quest/m1/README.md @@ -201,3 +201,6 @@ ladders. - [WebGPU on Safari](/quest/m1/webgpu-safari.md) - the WebGPU renderer is verified on Safari 26 for macOS and iOS - [A/V sync across a break](/quest/m1/watch-break-av-sync.md) - `@moq/watch` never plays pre-break audio out of sync with pre-break video - [moqsrc reconnect](/quest/m1/moqsrc-reconnect.md) - `moqsrc` redials after losing its relay and resumes on the same pads +- [moq fetch closes cleanly](/quest/m1/moq-fetch-close.md) - `moq fetch` closes its session before exiting instead of leaving the relay to time it out +- [Terminal dial errors](/quest/m1/moq-tokio-terminal-errors.md) - moq-tokio's reconnect loop stops on errors that can never succeed +- [Interop close log](/quest/m1/interop-close-log.md) - the interop idle-out check reads the relay close log at a pinned level diff --git a/quest/m1/interop-close-log.md b/quest/m1/interop-close-log.md new file mode 100644 index 0000000000..8268fe0a97 --- /dev/null +++ b/quest/m1/interop-close-log.md @@ -0,0 +1,22 @@ +# [XS] The interop idle-out check reads the relay's close log at a fixed level + +## Goal + +The interop harness's idle-out check never misreads a clean close as an open +connection because of the relay's log level. + +## Plan + +Found while merging #5174 (2026-10-10): the relay logs a clean +`connection closed` at info and an error close at warn, and the harness +counts those lines to decide every connection closed. If the interop relay +ever runs at warn, every clean close would read as still open and fail the +round. + +Decided 2026-10-10: pin the harness's relay log filter for the close-log +target to info in `test/interop/interop.sh`, so the product keeps warn for +error closes. Rejected: logging both at one level in moq-relay. Also fail +the round loudly when the relay log shows no connection for it, so a filter +that hides the `conn{id=...}` and close lines can't pass as nothing open. + +Public API: none. Wire: none. diff --git a/quest/m1/moq-fetch-close.md b/quest/m1/moq-fetch-close.md new file mode 100644 index 0000000000..2c8216e458 --- /dev/null +++ b/quest/m1/moq-fetch-close.md @@ -0,0 +1,26 @@ +# [XS] moq fetch closes its connection cleanly + +## Goal + +`moq fetch` (`rs/moq-cli/src/fetch.rs`) closes its session before exiting, +so the relay sees a clean close instead of timing the connection out. + +## Plan + +Found while merging #5174 (2026-10-10), which taught every interop client to +close cleanly and made the harness fail a round on an idled-out connection. +`moq fetch` still drops its connection without `Connection::close` or +`Client::close`; the js-native FETCH_DATA wire-compat cell reproduced the +relay timing it out. Only the wire-compat lanes reach it, and they skip the +idle-out check, so it doesn't fail CI today. + +Close the session the way #5174 did for the other clients, on every exit +after connecting, including an error or the `timeout_at` deadline. For the +regression, run a FETCH round with the current relay and the current +`moq fetch` under the idle-out check. No such round exists today (FETCH only +runs in the wire-compat lanes), so add one and wire it into CI. Don't enable +the check for the wire-compat cells: they mix in released relays and clients, +which it excludes because they may not close cleanly or log which connection +closed. + +Public API: none. Wire: none. diff --git a/quest/m1/moq-tokio-terminal-errors.md b/quest/m1/moq-tokio-terminal-errors.md new file mode 100644 index 0000000000..7a216b9f8d --- /dev/null +++ b/quest/m1/moq-tokio-terminal-errors.md @@ -0,0 +1,27 @@ +# [S] moq-tokio's reconnect loop gives up on errors that can never succeed + +## Goal + +With unlimited backoff, moq-tokio's reconnect loop stops and reports an error +that can never succeed on retry (a local dial or configuration error such as +`UnsupportedScheme`, an invalid URL, or a bad TLS configuration) instead of +retrying it forever. Transient errors keep retrying. + +## Plan + +Found while planning [moqsrc reconnect](/quest/m1/moqsrc-reconnect.md) +(2026-10-10): `moqsink` already reconnects with `backoff.timeout = 0`, and a +mistyped scheme makes it retry forever without a bus error. `moqsrc` will do +the same once it reconnects. + +Classify dial errors at the source: the loop already treats non-retryable +CONNECT statuses (`status_retryable`) as terminal; extend that to local +errors, listed by type rather than by message. The dial races QUIC and +WebSocket, so a local error is terminal only when every raced transport fails +terminally, as the CONNECT status check already requires; one transport +rejecting a scheme the other accepts must keep dialing. Fail loud with the +error. +Test with mocked time: an unsupported scheme fails at once under unlimited +backoff, and a refused TCP connect still retries. + +Public API: behavior only (the loop ends with the error). Wire: none.