Skip to content

feat!: lease qmux receive credit, one-segment floor, smaller windows, sized readiness - #7624

Merged
kixelated merged 17 commits into
mainfrom
quest/m1/unbounded-groups/fastest-reader
Nov 2, 2026
Merged

kixelated merged 17 commits into
mainfrom
quest/m1/unbounded-groups/fastest-reader

Conversation

@kixelated

@kixelated kixelated commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Fastest-reader pacing paused ingest only on native moq-quic. Several gaps remained:

  • qmux sessions (WebSocket, tcp://, tls://, unix://, WebRTC) read through poll::Buffered, which returns credit as it reads. Nothing bounded incomplete messages in aggregate (audit NET-3), and their streams never paused.
  • A leasing transport needed a 64 MiB floor, just to fit a legacy lite-01/02 ANNOUNCE_INIT. That forced 128 MiB client windows and 640 MiB peer windows.
  • group::Producer::ready() ignored the size of the next frame, so a large local frame still shed what the fastest reader had yet to take.

Approach

This implements the 2026-11-02 grill decisions below:

  • Sized readiness. group::Producer::poll_ready(waiter, &frame::Info) / ready(&info) wait until that frame fits within 16 MB of the fastest reader. They use the same poll_paced gate as ingest's admission, so the whole-frame exception carries over: a reader at the edge never stalls a frame larger than the window.
  • One-segment floor. lite-01/02 ANNOUNCE_INIT is capped at 1 MiB less its 16 bytes of prefixes, so MIN_RECEIVE_WINDOW is 1 MiB. An oversized legacy set fails the announce with EncodeError::TooLarge and is refused on decode.
  • Windows.
    • [quic] defaults are now 4 MiB receive, 1 MiB stream and 4 MiB send in moq-tokio and moq-uring. They were 128 MiB, 4 MiB and 16 MiB.
    • [limits.peer.quic] defaults are now 16 MiB receive and send, down from 640 MiB.
    • The floor checks (ReceiveWindowTooSmall, the relay, uring) follow the new minimum.
    • Docs and MIGRATE notes are updated.
  • qmux leases natively.
    • RecvStream drives moq-quic's mux lease API directly: credit is held until release, and a stuck window evicts the lowest-priority stream (Error::Evicted, CloseKind::Evicted). It also reports receive_window and answers poll_reset without reading.
    • The mux gained window accessors, credit_stats, and set_limits. qmux gained Session::set_limits and refuses a receive_window below the floor.
    • Buffered is now used only by iroh, which moq-dev/moq#7345 removes, and by test fakes.
  • qmux uses the same client/peer split as QUIC.
    • Every qmux session starts at the [quic] windows and stream count.
    • A client's qmux dials use its [quic], so links the relay dials take [limits.peer.quic].
    • server::Request::with_quic_limits also widens an accepted qmux session at ok(), so peers over WebSocket or TCP get [limits.peer.quic].
  • Streams waiting on TRACK_INFO give way first.
    • A lite GROUP stream ranks at the new priority::RECV_PARKED (below every group band) until its group opens, and a lite FETCH answer does while it waits unread on TRACK_INFO, then ranks as the group it fills instead of as a control stream. An ietf data stream waiting on its alias does too. A full window then evicts them before control streams, so TRACK_INFO still arrives. They reserve nothing from the paused budget.
    • They watch poll_reset meanwhile. moq-quic's recv::Stream::received_reset now fails with Evicted for an evicted stream until it is stopped, carried through moq-tokio, moq-uring, and qmux, so an evicted parked or paused stream stops at once. Before, an evicted stream whose reader held leased bytes kept further eviction off for good, so a parked stream could hold the window stuck.
    • A parked stream that fails withdraws its ticket, so the accept opens no group nobody fills.
  • Every qmux accept path takes [quic]. Server resolves [quic] once and gives it to its tcp://, tls://, unix://, and standalone WebSocket listeners and to tls_acceptor. websocket::Options::quic carries it for websocket::accept, which the relay fills from its [quic] through Web::with_quic. A WebRTC session keeps its fixed receive window at ok(), since that window sizes its read queue.
  • Quests.
    • Deleted quest/m2/qmux-receive-lease.md with quest rm and folded its Goal and Plan in.
    • Recorded the decisions and corrected the adapter inventory (moq-tokio has no Quinn backend, and moq-ffi goes through moq-tokio).
    • Moved whole-batch fills to flights.
    • Recorded the decisions below in the quest Plan and rewrote it to what remains: a two-relay chain test, a qmux per-session sweep, the quiet-host bench comparison, and JS parity behind the browser contract.

Measured bandwidth-delay needs

moq-quic sim (rs/moq-quic test harness, no congestion control, 10 Gbps link), 64 MiB through flow control (Mbps):

RTT conn / stream / send (MiB) 1 stream 16 streams
100 ms 4 / 1 / 4 (client) 67 272
100 ms 16 / 1 / 16 (peer) 67 1130
100 ms 32 / 4 / 32 272 2386
100 ms 128 / 4 / 16 (old client) 268 1130
250 ms 4 / 1 / 4 (client) 30 123
250 ms 16 / 1 / 16 (peer) 30 457
250 ms 16 / 4 / 16 120 499
250 ms 32 / 4 / 32 120 1023
250 ms 640 / 4 / 640 (old peer) 120 2147

moq-quic delivers about 80-90% of window/RTT. The old 16 MiB send window already capped the old 128 MiB client window.

Paused-stream budget at 4 MiB

Pacing still works at these windows. Fewer streams pause at once:

  • The budget is half the connection window, and each paused stream reserves a full stream window.
  • A client session (4 MiB / 1 MiB) pauses 2 group streams, and a peer link (16 MiB / 1 MiB, the stream window comes from [quic]) pauses 8.
  • Past that, groups read and shed as they did before pacing.
  • The 16 MB ahead window lives in the group cache, not in transport credit, so its depth is unchanged.

Decisions

Settled in the 2026-11-02 /quest-grill interview, and recorded in the quest Plan:

  1. Browser WebTransport
    • ✅ Native only. Browser parity is blocked until there is a real receive-credit contract.
    • Browser read-ahead cap.
    • Drop browser from scope.
  2. qmux
    • ✅ Handle it here, absorbing quest/m2/qmux-receive-lease.md.
    • Defer to receive-lease.
    • Add hooks here, but keep leases in m2.
  3. Lease floor
    • ✅ ANNOUNCE_INIT capped at one 1 MiB segment, so MIN_RECEIVE_WINDOW is 1 MiB everywhere. Exactly 1 MiB needs the cap at 1 MiB minus 16 bytes of prefixes.
    • 4 MiB cap.
    • Keep 64 MiB with a per-version floor.
  4. Client connection window
    • ✅ 4 MiB.
    • 16 MiB.
    • 32 MiB.
    • Keep 128 MiB.
  5. Client stream window
    • ✅ 1 MiB.
    • Keep 4 MiB.
  6. qmux windows
    • ✅ The same client/peer split as native QUIC.
  7. Peer and client send windows
    • ✅ Re-derive them in this PR, with peers around 16 MiB. Items 11 and 12 record the values chosen.
  8. Local readiness
    • ✅ Accept frame::Info.
    • A bare size on poll_ready / ready.
  9. Whole-batch fills
    • ✅ Move to flights.
    • Keep here.
  10. Branch collision

Settled by the maintainer on 2026-11-02, from the items this PR listed as needing a decision:

  1. Peer windows
    • ✅ Keep 16 MiB receive and send in [limits.peer.quic], with the 1 MiB stream window from [quic].
    • 32 MiB receive and send.
    • A separate per-stream peer window.
  2. Client send_window
    • ✅ 4 MiB, matching the client receive window.
    • Keep 16 MiB.
  3. GROUP streams waiting unread for TRACK_INFO while the paused budget is full
    • ✅ Let them wait at the lowest priority, so a full window cancels them before control streams.
    • Stop them outright.
  4. qmux sessions the relay accepts
    • ✅ Pass the configured [quic] windows into every accept path, including the relay's own WebSocket listener.
    • Leave the defaults.
  5. Scope
    • ✅ Split: land this PR as the windows, floor, qmux-lease, sized-readiness, TRACK_INFO-priority, and accept-path part, and rewrite the quest to what remains.
    • Finish everything here.

Choices made without asking, for review:

  • ietf data streams waiting on their alias, and lite FETCH answers, use the same lowest rank as parked GROUP streams. A lite FETCH answer now ranks as its group while it ingests, where it ranked as a control stream before.
  • Reporting an eviction through received_reset/poll_reset, which the parked wait needs and which also lets a paused stream that gets evicted stop.
  • WebRTC keeps its fixed receive window at ok() rather than widening to with_quic_limits.

Impact

  • moq-net (breaking): group::Producer::poll_ready / ready take &frame::Info. ANNOUNCE_INIT cap and MIN_RECEIVE_WINDOW drop to one segment.
  • Wire: lite-01/02 ANNOUNCE_INIT past about 1 MiB is refused on both ends, down from 64 MiB. Migrate: serve such an origin over lite-03+. No other format change: QMux MAX_DATA and STOP_SENDING only.
  • moq-tokio (breaking):
    • Default windows are 4 / 1 / 4 MiB, and ReceiveWindowTooSmall is at 1 MiB.
    • qmux sessions take the [quic] windows and can fail streams as evicted.
    • with_quic_limits applies to qmux.
    • New Error::QmuxLimits.
  • moq-relay (breaking defaults): [quic] is 4 / 1 / 4 MiB and [limits.peer.quic] is 16 / 16 MiB. Peers over WebSocket or TCP widen. Migrate: set the old values explicitly to keep them.
  • qmux (breaking):
    • RecvStream leases natively, with RecvLease.
    • New Error::Evicted, LeaseTooLarge, ReceiveWindowTooSmall, and Session::set_limits.
    • A receive_window below 1 MiB is refused.
  • moq-uring: default windows are 4 / 1 / 4 MiB.
  • moq-quic (behavior): recv::Stream::received_reset fails with Evicted for an evicted stream until it is stopped. Additive mux::Connection::{receive_window, stream_receive_window, credit_stats, set_limits}.
  • moq-net: transport::poll::RecvStream::poll_reset also reports an eviction, which a leasing transport must surface. New priority::RECV_PARKED.
  • moq-tokio (additive): websocket::Options::quic, tcp::Listener::with_quic, websocket::Listener::with_quic; driver received_reset fails with Evicted.
  • moq-relay: WebSocket sessions start at [quic]; embedders building web::Web pass it with Web::with_quic.

Alternatives

Grow-on-demand MAX_DATA for qmux was dropped: the one-segment floor makes a small static window cheap. Bounding Buffered with a refusing cap gives no backpressure.

Validation

  • just check passes on the pushed head (10216 tests), and just test receive-credit passes, including the qmux and uring Bun arms.
  • qmux session tests on every QMux draft:
    • partial messages evict the lowest-priority stream, and the others then progress;
    • a reset reaches an unread stream;
    • a window below the floor is refused.
  • announce_init_past_the_cap_fails covers the oversized legacy set.
  • a_local_writer_waits_for_room_for_its_frame covers sized readiness.
  • just test receive-credit (moq-tokio arm) passes, including the new Bun sender over WebSocket against a qmux receiver at the 1 MiB floor (receive_credit::javascript_partial_frame_gives_way_qmux).
  • qmux session tests also cover set_limits and a reset seen through a lease.
  • receive_credit::groups_waiting_for_track_info_give_way_first (moq-tokio, native QUIC, lite-07): GROUP streams for a SUBSCRIBE whose TRACK_INFO the publisher holds back fill the window beside an urgent track's partial frame. The waiting groups give way, the urgent frame completes, the TRACK_INFO arrives, and a waiting group is then read. It fails without the parked rank (the urgent frame is evicted) and without the poll_reset watch (the window stays stuck). 15 of 15 repeat runs passed.
  • a_failed_parked_stream_withdraws_its_group covers the withdrawal, and moq-quic's evicted_taken_bytes_keep_credit_until_stop now checks received_reset before and after the stop.
  • an_accepted_qmux_session_starts_at_the_configured_windows (a tcp:// session through a Server with a 2 MiB / 256 KiB [quic]) and an_upgraded_session_starts_at_the_options_windows (websocket::accept, the relay's path) each fail without the change.
  • The window table above comes from a scratch sim test, not committed.

Review

  • Reviewer: Codex gpt-6.1-sol, medium effort, through quest review --base origin/main, session 01a19e03-2c8b-7ea2-b870-795b8b2b651c. It is a new session, since the base's instruction files changed after the previous session (01a19d92-5e87-7ee2-9636-f8734f346f47, rounds 1-4, design checkpoint at round 4, last head 9bf847ca9f with no findings).
  • Reviewed head: 7b1b2627db2294a97792f17848c1f7ec7e719e37, round 3, no findings.
  • Round 1 (head 968d07bb74) found one issue, now fixed:
    • medium, rs/moq-tokio/src/quic/web/recv.rs: the public reset wait panicked on an eviction. Once the driver reported Evicted, RecvStream::received_reset (and web_transport_trait::RecvStream::closed) reached unreachable!. It now fails with ReadError, ReadError::Evicted included, and stuck_window_evicts_the_lower_priority asserts the driver's received_reset returns Evicted.
  • Round 2 (head fda2c9b59c): no findings.
  • Round 3 covered a merge of main with one hand-resolved conflict in rs/moq-relay/MIGRATE.md, which kept both Unreleased sections: no findings.

Follow-ups

  • Suggested quest: browser receive-credit contract. Waits on WebTransport exposing how much receive credit a stream the page stops reading holds, which browser and JS pacing (the quest's last item) need. Not created.

(Written by Claude Opus 5.5)

@kixelated kixelated changed the title Fastest-reader pacing chore(quest): checkpoint fastest-reader pacing capability audit Nov 2, 2026
kixelated and others added 9 commits November 2, 2026 09:51
… leases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nder over WebSocket; migration notes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ions

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d rate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title chore(quest): checkpoint fastest-reader pacing capability audit feat!: lease qmux receive credit, one-segment floor, smaller windows, sized readiness Nov 2, 2026
kixelated and others added 7 commits November 2, 2026 12:03
…ic] to every qmux accept

GROUP streams and FETCH answers waiting unread on TRACK_INFO (and ietf data
streams waiting on their alias) rank below every other stream, so a full
window evicts them before control streams. They watch poll_reset meanwhile,
which now reports an eviction: moq-quic's received_reset fails with Evicted
until the stream is stopped, through moq-tokio, moq-uring, and qmux, so an
evicted parked or paused stream stops and eviction resumes.

Every qmux session a server accepts starts at its resolved [quic] windows:
the tcp, tls, unix, and WebSocket listeners, the tls acceptor, and
websocket::Options, which the relay's own WebSocket path fills from [quic].
A WebRTC session keeps its fixed receive window at ok().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…emains

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…INFO

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on eviction

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	rs/moq-relay/MIGRATE.md
@kixelated
kixelated marked this pull request as ready for review November 2, 2026 20:59
@kixelated
kixelated added this pull request to the merge queue Nov 2, 2026

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed commit: 7b1b2627db2294a97792f17848c1f7ec7e719e37.

No actionable bugs found in the reviewed changes. The direction is sound: reuse moq-quic's existing lease/eviction machinery rather than add a separate qmux buffering policy, share the sized-readiness admission gate, and let parked streams observe eviction so they release their credit. The smaller windows are an explicit, documented throughput/memory tradeoff with configuration overrides.

The earlier local-review finding recorded in the PR body, the WebTransport reset wait panicking on eviction, is addressed by propagating ReadError::Evicted; it is not a new finding.

Verification limits: static GitHub source/diff inspection, including an independent moq-net review. I did not run builds, tests, interop, or benchmarks and have not independently validated the reported throughput figures.

(Written by OpenAI)

@coderabbitai

coderabbitai Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6c279695-adc8-4cbf-b0ad-cc2157a1a4b8
Commits

Reviewing files that changed from the base of the PR and between 29f9879 and 7b1b262.

Files selected for processing: 53
  • doc/bin/relay/config.md
  • quest/m1/unbounded-groups/fastest-reader.md
  • quest/m1/unbounded-groups/flights.md
  • quest/m2/README.md
  • quest/m2/qmux-receive-lease.md
  • rs/moq-net/MIGRATE.md
  • rs/moq-net/benches/group.rs
  • rs/moq-net/src/coding/reader.rs
  • rs/moq-net/src/fuzz.rs
  • rs/moq-net/src/ietf/subscriber.rs
  • rs/moq-net/src/lite/announce.rs
  • rs/moq-net/src/lite/message.rs
  • rs/moq-net/src/lite/publisher.rs
  • rs/moq-net/src/lite/subscriber.rs
  • rs/moq-net/src/model/group.rs
  • rs/moq-net/src/model/pace.rs
  • rs/moq-net/src/priority.rs
  • rs/moq-net/src/transport.rs
  • rs/moq-quic/MIGRATE.md
  • rs/moq-quic/src/connection/mux/mod.rs
  • rs/moq-quic/src/connection/streams/recv.rs
  • rs/moq-quic/src/connection/streams/state.rs
  • rs/moq-relay/MIGRATE.md
  • rs/moq-relay/src/limits.rs
  • rs/moq-relay/src/relay.rs
  • rs/moq-relay/src/uring.rs
  • rs/moq-relay/src/web.rs
  • rs/moq-relay/src/websocket.rs
  • rs/moq-tokio/MIGRATE.md
  • rs/moq-tokio/src/client.rs
  • rs/moq-tokio/src/error.rs
  • rs/moq-tokio/src/lib.rs
  • rs/moq-tokio/src/quic.rs
  • rs/moq-tokio/src/quic/driver/recv.rs
  • rs/moq-tokio/src/quic/driver/tests.rs
  • rs/moq-tokio/src/quic/web/recv.rs
  • rs/moq-tokio/src/server.rs
  • rs/moq-tokio/src/tcp.rs
  • rs/moq-tokio/src/unix.rs
  • rs/moq-tokio/src/webrtc.rs
  • rs/moq-tokio/src/websocket.rs
  • rs/moq-tokio/tests/integration/receive_credit.rs
  • rs/moq-uring/MIGRATE.md
  • rs/moq-uring/src/quic/driver/mod.rs
  • rs/moq-uring/src/quic/driver/recv.rs
  • rs/moq-uring/src/quic/transport.rs
  • rs/moq-uring/src/quic/web.rs
  • rs/qmux/MIGRATE.md
  • rs/qmux/src/config.rs
  • rs/qmux/src/error.rs
  • rs/qmux/src/session.rs
  • rs/qmux/src/session/tests.rs
  • test/receive-credit/sender.ts
Files with no reviewable changes: 2
  • quest/m2/README.md
  • quest/m2/qmux-receive-lease.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Walkthrough

The change reduces QUIC window defaults and sets a 1 MiB minimum receive window. QMux now leases receive credit, reports evicted streams, and supports runtime limit updates. Transport and relay paths pass configured limits into QMux sessions. Producer readiness accounts for the next frame’s size, and streams waiting for control information monitor resets. Lite ANNOUNCE_INIT is capped to one segment.

Merge Risk: Low · up to 7b1b2

WebRTC sessions can exceed a configured receive-buffer bound, but the per-session difference is bounded. This is mergeable with owner awareness of the WebRTC exception.

Pre-merge checks: Passed 4 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 76.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly identifies the main changes: qmux receive-credit leasing, the one-segment floor, smaller windows, and sized readiness. It is concise and relevant.
Description check Passed The description directly explains the receive-credit, window, readiness, eviction, compatibility, testing, and migration changes in the pull request.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 76.56% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 64 functions across 40 files. (11 skipped: 9 unsupported, 2 too large.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

Biome (2.5.15)
test/receive-credit/sender.ts

Biome could not lint this file: configuration resulted in errors. Check the repository's Biome configuration and plugins.

Clippy (1.99.0)

Clippy execution timed out

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Reviewed the full diff at 7b1b2627 (53 files): the qmux receive-lease rewrite, the one-segment floor, the smaller window defaults, sized readiness, the RECV_PARKED priority, and the qmux accept-path plumbing. I traced the eviction/credit bookkeeping end to end and tested the two highest-risk subsystems (qmux lease state machine; lite parked-stream lifecycle) with independent passes, both negative.

  • qmux native receive leases — RecvStream/RecvLease drive moq-quic's mux lease API directly; credit is held until release, a stuck window evicts the lowest-priority stream (Error::Evicted), and poll_reset reports evictions. Verified held/evicted_held/discard_lease/release_credit balance across poll_lease/poll_reset/stop/Drop/eviction, and that every in-tree caller drops an evicted reader so Drop stops the stream and frees the withheld credit.
  • One-segment floor — lite-01/02 ANNOUNCE_INIT caps at SEGMENT - 16, so MIN_RECEIVE_WINDOW resolves to one 1 MiB segment; oversized legacy sets fail loudly on both ends.
  • Smaller windows — clients default to 4/1/4 MiB in moq-tokio, moq-uring, and qmux; [limits.peer.quic] drops to 16 MiB; peers keep the [quic] 1 MiB stream window.
  • qmux client/peer split — every qmux accept path takes the server's [quic]; with_quic_limits widens peers at ok() (WebRTC keeps its read-queue-sized window); a rate cap qmux cannot pace fails admission with Error::QmuxLimits.
  • Parked-stream priority — streams waiting unread on TRACK_INFO rank at RECV_PARKED and watch poll_reset; a failed parked stream withdraws its group. Lock order is uniformly subscribes -> parked, no inversion.
  • Sized readiness — group::Producer::poll_ready/ready take &frame::Info and reuse poll_paced, whole-frame exception intact.

ℹ️ Sized readiness has no in-tree production consumer yet

group::Producer::poll_ready(&info) / ready(&info) now take the next frame's size, but the only callers in the tree are rs/moq-net/benches/group.rs and the pace.rs unit tests; no production local writer calls ready (nor did it before this PR). The whole-batch fill work moved to the flights quest, so I read this as deliberate API prep, but the local-writer shedding the PR describes only triggers once a writer waits on ready, so it may be worth naming the planned consumer in the quest before calling it landed.

Technical details
# Sized readiness consumer

## Affected sites
- `rs/moq-net/src/model/group.rs:2230` — `poll_ready(waiter, &frame::Info)`; the new 2-arg signature.
- `rs/moq-net/src/model/group.rs:2237` — `ready(&frame::Info)`.
- `rs/moq-net/src/model/pace.rs:2252` — `poll_paced(waiter, partial)` is the shared gate with ingest's `poll_admit`.

## Required outcome
- Either confirm the consumer is planned (flights / local writer) and note it where the quest marks sized readiness "landed", or wire the local writer in a follow-up.

## Open questions for the human
- Which local writer is expected to call `ready(&info)` first, and is it in scope for this PR or a later one?

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Merged via the queue into main with commit cc3c196 Nov 2, 2026
11 checks passed
@kixelated
kixelated deleted the quest/m1/unbounded-groups/fastest-reader branch November 2, 2026 22:14
kixelated added a commit that referenced this pull request Nov 3, 2026
Carries the waits onto main's sealed rustls crypto (#7028), freed receive
state (#7528), and qmux's leased receive credit (#7624):

- qmux's RecvStream leases and resets through moq-quic's poll_lease and
  poll_received_reset, with no readable map or driver kicks.
- moq-tokio's and moq-uring's received_reset wait on poll_received_reset and
  keep main's Evicted result; moq-tokio's poll form holds the stream's park.
- mux::Connection::set_limits wakes the transmit waiter, as QUIC's does.
- Doc links to the deleted handshake events point at the waits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant