feat(moq-net)!: gate broadcast announcements on a liveness flag - #2384
Closed
kixelated wants to merge 1 commit into
Closed
feat(moq-net)!: gate broadcast announcements on a liveness flag#2384kixelated wants to merge 1 commit into
kixelated wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Sorry @kixelated, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
Separate a broadcast's *existence* (registered in the origin tree, reachable
by a FETCH) from its *liveness* (advertised to `announced()` subscribers).
Publishing now registers a broadcast **offline**: `publish_broadcast` /
`create_broadcast` make it FETCH-routable but do not announce it until a
producer flips it live. This keeps an offline broadcast routable without
advertising it, the foundation for routing FETCH requests to offline
broadcasts.
Announcement is driven off the flag: the origin gates its announce stream on
liveness via a per-broadcast reconciler, announcing a live route and
unannouncing one that goes offline or closes, while existence stays in the
tree. Route selection (active vs backup at a path) is unchanged.
New surface (additive):
- rust: `broadcast::Producer::{set_live, is_live}`,
`broadcast::Dynamic::{set_live, is_live}`, and on `broadcast::Consumer`
`is_live` plus the async observer `live_changed` / `poll_live` (mirrors
`closed`/`poll_closed`, resolves `None` on close) so a consumer can react to
a broadcast going offline, matching the js `Consumer.live` signal
- ffi: `MoqBroadcastProducer::set_live`; libmoq: `moq_publish_set_live`
- py `set_live`, swift `setLive`, go `SetLive`, js `Broadcast.live` +
`setLive`
The FFI-based bindings' high-level `announce` verb marks the broadcast live
internally, so binding behavior is preserved (announce = discoverable now).
BREAKING CHANGE: in rust and js, publishing a broadcast no longer announces
it on its own; callers must call `set_live(true)` (or, in bindings, keep using
`announce`, which now implies liveness). No wire-format change: announce
already is the wire liveness signal, so no IETF draft update.
Interim API: `set_live` is a standalone flag for now. Once #2241 lands the
mutable `broadcast::Route { hops, cost }`, fold `live` in as a third field and
reconcile it through the same route observer, dropping the separate channel
and reconciler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kixelated
force-pushed
the
claude/broadcaster-announcements-api-c3e029
branch
from
July 18, 2026 03:08
08b616d to
11df534
Compare
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.
What
Separate a broadcast's existence (registered in the origin tree, reachable by a FETCH) from its liveness (advertised to
announced()subscribers), and drive announcement off a new per-broadcast liveness flag.Publishing now registers a broadcast offline:
publish_broadcast/create_broadcastmake it FETCH-routable but do not announce it. A producer callsset_live(true)to advertise it andset_live(false)to stop advertising while it stays routable.Why
Today the only way to reach a broadcast is via an announcement, so "exists" and "advertised" are the same thing. We want to route FETCH requests to offline broadcasts eventually, which means announcements should signal liveness, not existence. This PR makes that split: existence lives in the origin tree (what
request_broadcast/ a FETCH resolves against), and the announce stream is gated on the liveness flag. It also removes the accidental "announce before the catalog exists" race for callers that populate then go live.How
broadcast::{Producer,Dynamic}::set_live(bool)/is_live()andConsumer::is_live()back a liveness flag on the broadcast.API impact
Additive everywhere; nothing renamed or removed:
rs/moq-netbroadcast::{Producer,Dynamic}::{set_live,is_live}; onbroadcast::Consumeris_live+ the async observerlive_changed/poll_livers/moq-ffiMoqBroadcastProducer::set_livers/libmoqmoq_publish_set_live(newmoq.hsymbol)set_live/setLive/SetLive/Broadcast.live+setLiveBreaking (behavioral, not signature): in rust and js, publishing no longer announces on its own — callers must
set_live(true). Hence this targetsdev. The FFI-based bindings keep behavior: theirannounceverb marks the broadcast live internally, soannouncestill means "discoverable now" (additive only there).No wire change / no IETF draft update: announce already is the wire liveness signal.
cpp/obsunaffected (the C ABI change is a new function).Consumer observer:
broadcast::Consumerexposes an asynclive_changed(last) -> Option<bool>/poll_live(mirroringclosed/poll_closed;Noneon close), so a rust consumer can react to a broadcast going offline — parity with the jsConsumer.livesignal. The origin's own unannounce reconciler drives off this same observer.Interim API note
set_liveis a standalone flag for now. Once #2241 lands the mutablebroadcast::Route { hops, cost },liveshould fold in as a third field (Route { hops, cost, live }) reconciled through the same route observer, dropping this PR's separate liveness channel andreconcile_publishreconciler.liveis a genuine third axis, notcost = ∞: cost orders announced routes,live=falsemeans don't announce but stay FETCH-routable.Tests
moq-net: newtest_liveness_gates_announcement(offline = registered-but-not-announced and still FETCH-routable; toggling live drives announce/unannounce; unpublish removes it). Existing origin/announce suite updated for offline-by-default.moq-net,moq-native,moq-rtmp,moq-relay,moq-srt,moq-hls, and@moq/net(js, incl. a wire-level regression).cargo doc -D warnings(public items, CI-equivalent) clean.🤖 Generated with Claude Code