Repository navigation
Conversation
A publisher on a transport with reliable resets declares it in SETUP, and a lite-07 subscriber then waits for every counted stream without a grace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
moq-quic reports whether the peer accepted RESET_STREAM_AT, and the moq-tokio and moq-uring adapters forward that and a stream checkpoint to moq-net. The backend traits have no word for either, so moq-quic's types are recognized by downcast until web-transport-trait grows one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…or it A lite-07 endpoint declares the SETUP Reliable Reset parameter (0x6) when its transport keeps a reset stream's checkpoint. A subscriber whose publisher declared it waits for every counted Group Stream without the grace; datagram holes and older drafts keep it. @moq/net reads the declaration but never makes it. Adds a relay-hop test and the draft text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Quest outcome for Done:
Open:
(Written by Claude Opus 5.5) |
|
Superseded by moq-dev/moq#5983, which merged in fdbdcce. That's the maintainer's decision from 2026-10-19, relayed from an interactive session. #5983 restores SUBSCRIBE_DROP on lite-07 and removes This PR's signal (option 1) relied on The quest ( (Written by Claude Opus 5.5) |
|
Closing as superseded by #5983 (reasoning in #5804 (comment)). The quest deletion lands in #6041. (Written by Claude Opus 5.5) |
Problem
Quest:
quest/m1/quic/group-reset.md.A lite subscriber waits out a tail grace (the max delay, or 1s) when a publisher ends a subscription with a counted Group Stream still missing, because a stream reset before its header leaves no trace. moq-quic can already reset with RESET_STREAM_AT (#5690), but the lite publisher never used it for group headers, and nothing told the subscriber it could stop guessing.
Approach
transport::poll::SendStream::checkpoint()marks the data written so far for a laterresetto still deliver.transport::poll::Session::reliable_reset()says whether that holds (the peer acceptedreset_stream_at). Both are defaulted no-ops/false, so browser, qmux, and iroh report "no" without changes. moq-quic gainsConnection::reliable_reset(). The moq-tokio and moq-uring adapters forward both. The in-memory transport models it (memory::Config::reliable_reset, truncating a reset stream to the checkpoint).Stream Countonly once its GROUP message is flushed, and is checkpointed right there. Counting is applied on every session, not just declaring ones: a stream reset before its header was never visible anyway.Reliable Reset(0x6, flag). An endpoint sends it when its version has aStream Countand its transport reportsreliable_reset(). A relay never forwards it; each hop declares its own transport.Settle::exactin Rust,settle(..., { exact: true })in@moq/net). Datagram holes are not counted, so they cannot hang it. lite-05/06 keep the grace, since their accounting cannot tell a datagram hole from a stream in flight.@moq/netreads the declaration but never makes it: the browser cannot reset that way.draft-lcurley-moq-lite.md: the parameter, the counting rule, RESET_STREAM_AT on Group Streams, the subscriber's unbounded wait, and the lite-07 changelog.Decision for the maintainer: the signal's wire shape
Stream Count.Recommendation: ship 1 now. It is the smallest change that removes the grace where it is safe. Revisit 3 when the subscribe-drop quest settles, since option 3 makes this parameter redundant. The two conflict today: that quest wants to restore DROP and drop
Stream Count, and this design relies on the count to exclude datagrams.Impact
Public API (Rust):
moq_net::transport::poll::Session::reliable_reset(&self) -> bool(defaulted).moq_net::transport::poll::SendStream::checkpoint(&mut self)(defaulted).moq_net::transport::memory::Config::reliable_reset(the struct isnon_exhaustive).moq_net::lite::Setup::reliable_resetfield andSetup::detect_reliable_reset.moq_quic::Connection::reliable_reset(), plusreliable_reset()on the moq-tokio and moq-uring QUIC connections.Public API (JS):
Setup.reliableReset/SetupProps.reliableResetin@moq/netlite.Wire: lite-07 (
moq-lite-07-wip) only. New SETUP parameter 0x6. A declaring publisher resets counted Group Streams with RESET_STREAM_AT. lite-05/06 and IETF are unchanged on the wire. On every lite version, a Group Stream reset before its GROUP message is written is no longer counted.Stopgap
web-transport-trait 0.5 has no checkpoint or reliable-reset method, so the moq-tokio and moq-uring adapters recognize moq-quic's types by
Anydowncast. The clean fix is defaultedcheckpoint()andreliable_reset()methods upstream in web-transport-trait, at which point the downcasts go away.Verification
cargo clippy -p moq-quic -p moq-tokio -p moq-uring -p moq-net --all-features --tests -D warnings: clean. moq-uring is also clean with--no-default-features, apart from pre-existing dead-code warnings.cargo test -p moq-net --all-features: passes.cargo test -p moq-tokio --lib: passes.reset_stream_attests and moq-uringweb::integration tests: pass.a_reset_group_that_keeps_its_header_ends_without_the_grace: hangs without the checkpoint.reset_delivers_the_checkpointand moq-uringa_reset_stream_keeps_its_checkpoint: real moq-quic, through the moq-net adapters.@moq/netlite-07 waits past the grace ... declared.a_declared_publisher_is_waited_on_past_the_graceanda_declared_publisher_is_waited_on_through_a_relay(relay hop), plus setup round-trip tests in both languages.bun testin js/net (1939 pass) andtsc --noEmit: pass.just drafts check: passes.test/interop/interop.sh --tail --publishers rust --subscribers rust,js-native-bun: all Rust and JS tail lanes pass. These lanes negotiate lite-06, so they cover the counting change but not the signal.just checkwas not run, to keep the build scoped on a shared machine.Not done (follow-ups)
INTEROP_VERSIONcurrently turns on compat mode, which skips them.reset_stream_atis treated as unable to keep it.checkpoint/reliable_resetin web-transport-trait and drop the downcasts.🤖 Generated with Claude Code