Skip to content

refactor(net)!: moq-net names say one thing - #6751

Merged
kixelated merged 76 commits into
mainfrom
quest/m1/api-audit/net-names
Oct 27, 2026
Merged

kixelated merged 76 commits into
mainfrom
quest/m1/api-audit/net-names

Conversation

@kixelated

@kixelated kixelated commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

moq-net and @moq/net names collided with other items (stats::Control vs track::Control, stats::Bytes vs bytes::Bytes, transport::Stats vs session::Stats, JS Reservation.grant vs Auth.Grant, and a reservation's rate named peek() in Rust, grant() in the bindings, and rate in JS), described the wrong shape (Session::bandwidth() returns an allocator beside the send_bandwidth()/recv_bandwidth() estimates), or did not mirror each other (Rust query() vs JS info(), JS writeGroup vs Rust create_group). Quest: quest/m1/api-audit/net-names.md.

Approach

One commit per decided rename, each carried through every caller, binding, and doc that exposes it. transport::Metrics drops the byte counts, and session::Stats reads them from the transport's Wire.

Impact

All breaking; rs/moq-net, js/net, rs/moq-tokio, rs/moq-ffi, rs/moq-c, and each wrapper's MIGRATE.md say how to migrate. Wire: none.

  • moq-net: Session::bandwidth() → allocator(), Client::with_bandwidth → with_allocator, auth::Auth → auth::Credential, track::Consumer::query()/track::Querying → info()/track::Resolving, bandwidth::Reservation::consumer() → consume(), bandwidth::Reservation::peek() → rate(), stats::Control → stats::Message, stats::Bytes → stats::Totals.
  • moq-net: group::Demand drops is_used/used/unused/poll_used/poll_unused for wanted(), wanted_changed(), and poll_wanted_changed(), like track::Demand.
  • moq-net: transport::Stats → transport::Metrics without bytes_sent/bytes_received; poll::Session::stats() → metrics(), now defaulted; transport::StatsUnavailable is gone.
  • moq-tokio: Connection::bandwidth() → allocator().
  • @moq/net: Auth.Auth → Auth.Credential, Reservation.grant → rate, a connection's bandwidth → allocator, and Track.Producer.writeGroup(group) → createGroup(sequence), which returns the new group.
  • moq-ffi: MoqBandwidth → MoqAllocator and MoqSession::bandwidth() → allocator(); each wrapper's Bandwidth/bandwidth() → Allocator/allocator(). MoqReservation::grant() → rate(), and each wrapper's Reservation.grant() (Go Grant()) → rate() (Go Rate()). Python's and Swift's nested Bandwidth.Consumer is now the top-level BandwidthConsumer, as in Kotlin, Dart, and C++. Producer options keep their bandwidth field, like moq-audio/moq-video.
  • moq-c: moq_session_bandwidth → moq_session_allocator, moq_bandwidth_reserve → moq_allocator_reserve, moq_bandwidth_close → moq_allocator_close, moq_reservation_grant → moq_reservation_rate. The C ABI is not frozen: its Unreleased MIGRATE already carries layout-breaking changes. The receive-estimate names (recv_bandwidth, moq_bandwidth_consumer_*) stay.

Choices made without asking, for review:

  • poll::Session::stats() is also renamed metrics(), so the method names what it returns.
  • moq-tokio sessions over a backend without wire counters (Iroh) keep a wire that metrics() refreshes from the backend's byte stats, so Iroh still reports bytes; the registry sees them only once something samples the session.
  • JS createGroup takes a sequence and builds the group like Rust's create_group and @moq/e2ee's createGroup, rather than only renaming writeGroup(group). So a group can no longer be written before joining a track, or join two tracks; the three tests for that path are gone, and so is the groupStart hook.
  • JS's connection bandwidth became allocator too, since it has the same collision beside probe.

Alternatives

  • Rename writeGroup to createGroup(group) only: keeps prefilled and shared groups, but createGroup would then take two shapes within JS.
  • Drop Iroh's session byte counts, not add a polled wire: simpler, but a regression.

Decisions

  • What do Rust, the bindings, and the C ABI call a reservation's current slice? (JS calls the watchable signal rate, read with rate.peek().)

    • peek() / moq_reservation_peek, matching Rust before this PR (recommended at the time)
    • rate() / moq_reservation_rate, matching JS's rate ✅ (maintainer, 2026-10-25)
    • keep grant() in the bindings

    JS keeps its signal-free Reservation.peek(), which reads the registry directly after a synchronous update(), beside the rate signal.

Merging main: moq-dev/moq#6428 dropped the JS per-name sequence namespace, so its replacement tests resolve to main's "a replacement producer starts over", now written with createGroup. The later merge renames main's new track::Consumer::query() callers (lite and IETF publishers, the fuzz bench helper) to info() and its new auth::Auth uses to Credential, keeps both sides' MIGRATE entries, fixes the Python and Swift docs that still named Bandwidth.Consumer, and regenerates the Dart bindings and @moq/net API report. The third renames the configured-token code from moq-dev/moq#6177 (moq-tokio's auth::Auth and @moq/net's Auth, which connection/tokens.ts imports as Presented beside its own internal dial Credential) and carries the renames into the merged binding docs. The fourth keeps main's now-used InFlight::accepted beside this branch's track::Resolving, keeps both moq-tokio MIGRATE entries, and drops main's new quest/m1/api-audit/wanted.md blocker on this one, noting that group::Demand already says wanted. The fifth keeps both sides' Unreleased MIGRATE entries beside moq-dev/moq#6745's decoder reads, the sixth takes moq-dev/moq#6851's async-only lint reason on stats::Session::control with stats::Message, and the seventh regenerates the @moq/net report under moq-dev/moq#6794's API Extractor and carries the Session allocator entry into the hand-written 0.7 history that moq-dev/moq#6052's generated c/moq/MIGRATE.md copies. The eighth carries the renames into moq-dev/moq#6781's simulcast rungs (MoqAllocator option types, Reservation::rate()/consume(), moq_allocator_* in the C tests, main's new query() and JS writeGroup callers), keeping its idle-reservation MIGRATE entries in the new names. The ninth merges moq-dev/moq#6750: finish()/abort() with createGroup(), dropping its shared-group and prefilled-group tests that createGroup rules out, and one hole-fill test now awaits the group's asynchronous finish. The tenth takes moq-dev/moq#6834, which replaced the per-token binding handles (MoqAuth, MoqAuthToken, each wrapper's Auth/AuthToken) with MoqSession.tokens()/grants(), so the binding-level Credential rename and its MIGRATE entries are gone; moq-net's auth::Auth is still renamed Credential, including the session fields #6834 added.

Checks: just check (all lanes the branch touches, including 8868 Rust tests; on the bindings commit, dart's RSS-bounded leak_test.dart failed once under the parallel load and passes alone), just rs wasm, just test interop --all, and bun test in net, hang, watch, e2ee, publish, and room all pass. After the rate() rename and merging main: just check (js, rs with 8865 tests, markdown, gh, quest, obs, drill, lints) plus just py check/test, kt check (the Kotlin wrapper build and JVM tests), go check, cpp check, obs compile, and dart check pass. Not run: the Swift wrapper (no macOS here). After the latest merge of main: just check passes every lane it selects (rs, js, py, kt, swift, go, cpp, obs, dart, markdown, quest, and the rest). just rs features and just rs loom fail on errors this PR does not touch, which origin/main has too: moq-net's rustdoc links (crate::Session::closed, Self::unused in track/fill.rs, and three private-item links), moq-tokio's open_request unused in one tokio-features combination, and tests/loom.rs calling the now-private Broadcast::route() and the removed Subscription::with_groups. The rest of features (quic, media, --no-default-features) passes. After the fourth through sixth merges of main: just check passes every lane it selects (rs, js, py, kt, go, cpp, obs, dart, markdown, quest, and the rest; Swift skips without a toolchain here) after each, and just test interop --all passes after the fifth. After the seventh: just check passes every lane it selects (rs with 9068 tests, c, cpp, js, py, kt, go, obs, dart, markdown, gh, quest, toml, nix, and the rest; Swift skips without a toolchain), and so does just test interop --all.

After the eighth through tenth merges: just check passes every lane it selects (rs, c, cpp, obs, js, py, kt, go, dart, markdown, gh, quest, toml, nix, and the rest; Swift skips without a toolchain), and so does just test interop --all.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

kixelated and others added 21 commits October 24, 2026 23:56
transport::Metrics drops the byte counts transport::Wire already holds;
session::Stats reads them from the wire.

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

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>
… frees cache

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MoqAuthToken is MoqCredential, and each wrapper's AuthToken is Credential.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mirrors JS Track.Consumer.info().

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
writeGroup inserted a caller-built group; createGroup builds it, like Rust's
create_group and e2ee's createGroup. Sharing one group between tracks goes.

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>
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>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
finish() declares the end without closing, abort(err) is terminal, and
close() releases the handle like a Rust drop: clean with a declared end,
otherwise a Cancel abort. Producer.closed and Demand.closed now settle on
the outcome, including a reached and settled end; the wire layer watches
the release through private hooks.

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

Lister.ended is renamed closed. Group and broadcast Demand.unused now
reject once the handle closes, as Rust's do, instead of reading a closed
handle as unused. Subscriber.end() and Ordered.end() are removed: readers
await finished(); publishers read the snapshot through a private hook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title moq-net names say one thing refactor(net)!: moq-net names say one thing Oct 25, 2026
@kixelated
kixelated marked this pull request as ready for review October 25, 2026 09:40
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-27T08:09:17.460268Z 133c1a5 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

kixelated and others added 2 commits October 25, 2026 02:43
A consume() handle shares the producer's state, so its close() ended the
group for every reader. close() now takes no error and releases only this
handle: a shared handle ends its own reads, a mirror closes its own copy.
Wire and track fan-out fail a reader's copy through a private hook.

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

@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: 284515e

No actionable bugs found in the inspected changes. Consistent names and the narrower JS createGroup ownership API are a coherent direction. Rust allocator/credential/info/stats callers, binding credential wrappers, group demand watchers and transport Wire/metrics snapshot handling remain aligned through the migration.

Verification: static GitHub inspection of the changes and relevant surrounding code only. No builds, binding regeneration, tests or interoperability checks executed.

Mirror moq_net::bandwidth::Allocator and Session::allocator() across
moq-ffi, every hand-written wrapper, OBS, and moq-c
(moq_session_allocator, moq_allocator_reserve, moq_allocator_close).
Python and Swift move the nested Bandwidth.Consumer to a top-level
BandwidthConsumer, matching Kotlin, Dart, and C++.

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

@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: 59da867
Compared with previous review at 284515e.

No actionable bugs found in this update. Extending Allocator naming through UniFFI, language wrappers, OBS and the C ABI keeps the public surface aligned. The Python/Swift BandwidthConsumer move and retained producer bandwidth options are documented. Inspected caller migrations, Dart native symbols/converters and C++ binding generation.

Verification: static GitHub inspection only; no builds, binding regeneration or tests executed.

moq-audio's capture logs a finished track's Ok outcome, the drain and
compat clients finish their groups, rustfmt, and the quest now covers only
the JS consumers whose close() still ends shared state.

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

Main's no-async model gate (#6851) builds tests without the async read_frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated added this pull request to the merge queue Oct 27, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 27, 2026
kixelated and others added 2 commits October 26, 2026 20:28
…fecycle

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

#6815's IETF range updates finish their group producers, finish tracks before closing them, and release an excluded group's reader through the private releaseGroupReader hook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated and others added 5 commits October 26, 2026 21:45
…n group below the end

A prune that evicts the open group holding the end back now re-checks the outcome, as the Rust poll_outcome does once the evicted slot leaves its lookup.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#6900's new bench ends them with the pre-split close().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A received copy's tail grace is judged when polled, so a later subscription with a longer max delay could reopen an end closed() already reported, and an abort within it turned it into an error. poll_outcome now latches the clean outcome it returns, as JS does by settling before a subscription change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Carry the renames into #6781 (simulcast rungs): MoqAllocator option types,
Reservation::rate()/consume(), moq_allocator_* in the C tests, and keep
both sides of the Unreleased MIGRATE entries. Rename main's new
track::Consumer::query() and JS writeGroup callers, and regenerate the Dart
bindings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated and others added 2 commits October 26, 2026 23:27
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep both Unreleased MIGRATE entries, take finish()/abort() with createGroup(),
drop the shared-group and prefilled-group tests that createGroup rules out, and
carry group::Demand's new closed() docs beside wanted_changed().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#6834 replaced the per-token handles (MoqAuth, MoqAuthToken, and each
wrapper's Auth/AuthToken) with MoqSession.tokens()/grants(), so the
binding-level Credential rename and its MIGRATE entries go; moq-net's
auth::Auth is still renamed Credential, now including the session fields
#6834 added. Keep Allocator/BandwidthConsumer in the wrappers beside the new
GrantConsumer and Tokens, take #6834's binding docs and OBS token flow, and
regenerate the Dart bindings. #6750 merged as a squash, so its conflicts
resolve to the earlier merge of its head.

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

Copy link
Copy Markdown
Collaborator Author

Merged main again after moq-dev/moq#6750 and moq-dev/moq#6834 landed, then landing 133c1a595183b46ae94a7122c19a42186cfc439a.

  • moq-dev/moq#6781: its simulcast-rung code now uses MoqAllocator, Reservation::rate()/consume(), and moq_allocator_*; its idle-reservation MIGRATE entries are kept, in the new names.
  • moq-dev/moq#6750: finish()/abort() combined with createGroup(). Its shared-group and prefilled-group tests are dropped, since createGroup rules both out, and one hole-fill test now awaits the group's asynchronous finish.
  • moq-dev/moq#6834 deleted the per-token binding handles (MoqAuthToken and each wrapper's AuthToken), so the binding-level Credential rename and its MIGRATE entries are gone. moq-net's auth::Auth is still renamed Credential, including the session fields feat(auth)!: per-connection tokens with an answer, and a grant consumer #6834 added.

Checks: just check passes every selected lane, Swift excepted (no toolchain here). just test interop --all passes, and so does quest check.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 2adc1c0 Oct 27, 2026
12 checks passed
@kixelated
kixelated deleted the quest/m1/api-audit/net-names branch October 27, 2026 09:22
kixelated added a commit that referenced this pull request Oct 27, 2026
Merge origin/main brought #6751, which renamed Track.Producer.writeGroup
to createGroup. The interop probe fixture now drives the clock until the
estimate lands, and the announce teardown test uses closeUnwanted like
Connection.announced.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 27, 2026
Carry #6751's renames into the draft 14-17 removal: stats::Message,
Session::allocator(), track info(), and keep both MIGRATE entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 27, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 27, 2026
Carry the lifetime-free Path into #6752's requests() rename and #6751's stats/auth names.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant