feat(moq-net): add OriginProducer::dynamic + infallible OriginConsumer::request_broadcast#1913
Merged
Merged
Conversation
…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>
Contributor
|
Caution Review failedPull request was closed or merged during review WalkthroughAdds a kio 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches✨ Simplify code
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. Comment |
4 tasks
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ports the origin-level dynamic-fallback API from
devtomain:OriginProducer::dynamic()(from #1772) and an infallibleOriginConsumer::request_broadcast(from #1890).On
devthese ride on a chain of disruptive reshapes that are deliberately quarantined there (TrackInfo/TrackConsumer#1631, RAIIOriginPublish#1640, lite-05 wire #1847). Rather than drag those intomain, this reimplements the feature additively againstmain's existing primitives. It turned out the dynamic machinery is self-contained onkio+OriginNodes, so the port is small and touches no existing API —subscribe_trackand 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 ofBroadcastProducer::dynamic).OriginConsumer::request_broadcast(path) -> kio::Pending<BroadcastRequested>— looks up an announced broadcast (resolves immediately), else registers a fallback request that resolves once anOriginDynamichandleraccepts it. Concurrent requests for the same path coalesce.OriginDynamic,BroadcastRequest,BroadcastRequested.Error::Unroutableat wire code30(matchesdev; 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 onWaiter).Consumer::write(), so the requester can enqueue into the shared dynamic queue (mirrorsProducer::write).Infallibility
request_broadcastis infallible on its own terms — it returns akio::Pendingfuture, not aResult. An announced path resolves immediately; an unannounced path stays pending until served, then resolves to the broadcast or toError::Unroutable(no route) /Error::Dropped(origin gone). This required no change tosubscribe_track, which stays-> Result<...>as onmain.API notes
This adds new public
moq-netsurface but is purely additive (no existing signature changes), so it'smain-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::accepttakes aBroadcastConsumerdirectly instead of dev'sConsume<T>trait. That trait is part of the #1640 RAII reshape and pulling it in would changepublish_broadcast's signature, which is out of scope here.Follow-ups (Cross-Package Sync) — intentionally not in this PR
js/netmirror +doc/conceptpy/swift/kt/gowrapper surface (dev's feat(moq-net): add OriginDynamic for unannounced fallback broadcasts #1772 mirrored this)Test plan
cargo test -p kio -p moq-net— passes, including 8 newdynamic_*tests (ported and adapted to main's API) and the kioPendingtestcargo fmt+cargo clippy -p kio -p moq-net(via nix) cleanmoq-relay,moq-native,hang,moq-mux,moq-ffi,moq-clijust check(JS + native matrix) not run — change is Rust-only and additive🤖 Generated with Claude Code
(Written by Claude)