Skip to content

feat(moq-net): add OriginProducer::dynamic + infallible OriginConsumer::request_broadcast#1913

Merged
kixelated merged 1 commit into
mainfrom
claude/gallant-pasteur-e488d0
Jun 26, 2026
Merged

feat(moq-net): add OriginProducer::dynamic + infallible OriginConsumer::request_broadcast#1913
kixelated merged 1 commit into
mainfrom
claude/gallant-pasteur-e488d0

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Summary

Ports the origin-level dynamic-fallback API from dev to main: OriginProducer::dynamic() (from #1772) and an infallible OriginConsumer::request_broadcast (from #1890).

On dev these ride on a chain of disruptive reshapes that are deliberately quarantined there (TrackInfo/TrackConsumer #1631, RAII OriginPublish #1640, lite-05 wire #1847). Rather than drag those into main, this reimplements the feature additively against main's existing primitives. It turned out the dynamic machinery is self-contained on kio + OriginNodes, so the port is small and touches no existing API — subscribe_track and the rest of the origin/track surface are unchanged.

What changed

moq-net

  • OriginProducer::dynamic() -> OriginDynamic — serves whole broadcasts on demand. Served broadcasts are never announced, so they only resolve a consumer's exact-path request when no live announcement exists (the origin-level analogue of BroadcastProducer::dynamic).
  • OriginConsumer::request_broadcast(path) -> kio::Pending<BroadcastRequested> — looks up an announced broadcast (resolves immediately), else registers a fallback request that resolves once an OriginDynamic handler accepts it. Concurrent requests for the same path coalesce.
  • New types: OriginDynamic, BroadcastRequest, BroadcastRequested.
  • Error::Unroutable at wire code 30 (matches dev; codes 28/29 stay reserved for dev's compression/timestamp errors so the wire code is identical across branches).

kio (additive)

  • Future + Pending (future.rs, ported verbatim — depends only on Waiter).
  • Consumer::write(), so the requester can enqueue into the shared dynamic queue (mirrors Producer::write).

Infallibility

request_broadcast is infallible on its own terms — it returns a kio::Pending future, not a Result. An announced path resolves immediately; an unannounced path stays pending until served, then resolves to the broadcast or to Error::Unroutable (no route) / Error::Dropped (origin gone). This required no change to subscribe_track, which stays -> Result<...> as on main.

API notes

This adds new public moq-net surface but is purely additive (no existing signature changes), so it's main-appropriate per Branch Targeting. New public items: OriginProducer::dynamic, OriginConsumer::request_broadcast, OriginDynamic, BroadcastRequest, BroadcastRequested, Error::Unroutable, kio::{Future, Pending}, kio::Consumer::write.

One deliberate divergence from dev: BroadcastRequest::accept takes a BroadcastConsumer directly instead of dev's Consume<T> trait. That trait is part of the #1640 RAII reshape and pulling it in would change publish_broadcast's signature, which is out of scope here.

Follow-ups (Cross-Package Sync) — intentionally not in this PR

Test plan

  • cargo test -p kio -p moq-net — passes, including 8 new dynamic_* tests (ported and adapted to main's API) and the kio Pending test
  • cargo fmt + cargo clippy -p kio -p moq-net (via nix) clean
  • reverse-deps compile: moq-relay, moq-native, hang, moq-mux, moq-ffi, moq-cli
  • full just check (JS + native matrix) not run — change is Rust-only and additive

🤖 Generated with Claude Code

(Written by Claude)

…r::request_broadcast

Port the origin-level dynamic-fallback API from dev to main, reimplemented
against main's existing primitives rather than dragging in the dev-only
reshapes it rides on there (TrackInfo/TrackConsumer #1631, RAII OriginPublish
#1640, lite-05 wire #1847). subscribe_track and the rest of the origin/track
API are left untouched.

`OriginProducer::dynamic()` returns an `OriginDynamic` handler that serves
whole broadcasts on demand. The served broadcasts are never announced, so they
only resolve a consumer's exact-path request when no live announcement exists.

`OriginConsumer::request_broadcast(path)` is infallible on its own terms: it
returns `kio::Pending<BroadcastRequested>` that resolves immediately for an
announced broadcast, stays pending until a handler serves an unannounced one,
or resolves to `Error::Unroutable` when no route exists (and `Error::Dropped`
once the origin is gone). The call itself never returns a Result.

The dynamic machinery is self-contained on kio plus main's existing
OriginNodes, so the only supporting additions are:

- kio: `Future` + `Pending` (`future.rs`, ported verbatim) and a
  `Consumer::write()` so the requester can enqueue into the shared queue.
- moq-net: `Error::Unroutable` at wire code 30, matching dev so the code is
  identical across branches (28/29 stay reserved for dev's compression/
  timestamp errors).

`BroadcastRequest::accept` takes a `BroadcastConsumer` directly instead of
dev's `Consume<T>` trait, which belongs to the #1640 RAII reshape and would
otherwise change `publish_broadcast`'s signature.

Ports the 8 dynamic_* unit tests, adapted to main's API.

Follow-ups (Cross-Package Sync), intentionally not in this PR: js/net mirror,
doc/concept, the FFI/libmoq + language-wrapper surface, and relay wiring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kixelated kixelated merged commit 6b038df into main Jun 26, 2026
1 check passed
@kixelated kixelated deleted the claude/gallant-pasteur-e488d0 branch June 26, 2026 04:41
@moq-bot moq-bot Bot mentioned this pull request Jun 26, 2026
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

Adds a kio Future trait and Pending adapter for std::future::Future, plus Consumer::write for mutable state access. Re-exports the new kio types from rs/kio/src/lib.rs. In moq-net, adds Error::Unroutable and maps it to wire code 30. OriginProducer and OriginConsumer now share a dynamic queue for unannounced broadcast requests, and new origin dynamic request types handle polling, acceptance, rejection, and tests.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main moq-net API additions and matches the changeset.
Description check ✅ Passed The description is directly related to the ported dynamic-fallback API and supporting kio changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/gallant-pasteur-e488d0

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

Comment @coderabbitai help to get the list of available commands.

kixelated added a commit that referenced this pull request Jun 26, 2026
Port the moq-rtc gateway from the dev branch. It bridges WebRTC and MoQ,
speaking WHIP (publish) and WHEP (subscribe) in either HTTP role, so it can
accept incoming peers (OBS, browsers) or dial out to a remote WebRTC server.
All four paths work; ingest covers H.264/VP8/VP9/Opus and egress adds
H.265/AV1, using str0m for ICE/DTLS/SRTP and a shared single-UDP-port mux.

Adapted to main's current APIs: `Broadcast`/`Track` model, infallible
`OriginConsumer::request_broadcast` + `OriginProducer::dynamic` (#1913),
`BroadcastConsumer::subscribe_track`, `publish_broadcast` lifetime tied to the
producer, moq-mux's in-place H.264 `Import` (avc3 mode), and moq-native's
`with_publish`/`with_consume` client builder.

Wires the crate into the workspace and documents it (doc/bin/rtc.md, index,
sidebar, crate map).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Jun 26, 2026
Port the moq-rtc gateway from the dev branch. It bridges WebRTC and MoQ,
speaking WHIP (publish) and WHEP (subscribe) in either HTTP role, so it can
accept incoming peers (OBS, browsers) or dial out to a remote WebRTC server.
All four paths work; ingest covers H.264/VP8/VP9/Opus and egress adds
H.265/AV1, using str0m for ICE/DTLS/SRTP and a shared single-UDP-port mux.

Adapted to main's current APIs: `Broadcast`/`Track` model, infallible
`OriginConsumer::request_broadcast` + `OriginProducer::dynamic` (#1913),
`BroadcastConsumer::subscribe_track`, `publish_broadcast` lifetime tied to the
producer, moq-mux's in-place H.264 `Import` (avc3 mode), and moq-native's
`with_publish`/`with_consume` client builder.

Wires the crate into the workspace and documents it (doc/bin/rtc.md, index,
sidebar, crate map).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kixelated kixelated mentioned this pull request Jun 30, 2026
4 tasks
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