feat(moq-net): request_broadcast returns Unroutable when no route exists#1779
Merged
Conversation
`OriginConsumer::request_broadcast` previously failed with `NotFound` when a path was neither announced nor served by an `OriginDynamic` handler, which is indistinguishable from a track/broadcast genuinely not existing. Add a dedicated `Error::Unroutable` (wire code 30) and return it both synchronously (no handler live) and when a registered request loses every handler before being served. Also adds a regression test for the accept/dynamic race: once a handler picks a request up, `accept` still resolves the requester even if every handler drops first and flips the dynamic count to zero. The in-flight request is decoupled from the count, so it is not spuriously rejected as Unroutable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VhPahy17b2FWxDdz1ugFqm
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
Follow-up to #1772 (the new
OriginConsumer::request_broadcast). Two asks:Return
Unroutableinstead ofNotFound.request_broadcastpreviously failed withError::NotFoundwhen a path was neither announced nor served by anOriginDynamichandler. That's indistinguishable from a track/broadcast that genuinely doesn't exist, so this adds a dedicatedError::Unroutable(wire code30) meaning "no announcement and no dynamic router, so there is no route to this broadcast." It is returned in both failure modes:dynamic == 0);An explicit
BroadcastRequest::reject(err)still surfaces the handler's own error unchanged.Checked the "accept before dynamic" race. Conclusion: the model is race-free.
OriginDynamic::new/clone/dropand thedynamic == 0check inrequest_broadcastall mutate the count under the same lock, so a handler that is live whenrequest_broadcastacquires the lock always registers the request rather than rejecting it. Crucially,acceptis decoupled from the count: once a handler has picked a request up viarequested_broadcast, theBroadcastRequestowns the result channel, so it can stillacceptand resolve the requester even after every handler (itself included) drops and flips the count to zero. Addeddynamic_request_accept_after_handler_droppedto lock that in.The only remaining race is caller-ordering: if
request_broadcastruns before a handler is created, it fails fast withUnroutable. That's the same race the track-level code already addresses by creating the dynamic handler before announcing (seelite/subscriber.rs:414), and the synchronous increment inOriginDynamic::newmakes the same "create before expose" discipline sufficient here. No relay site wiresOriginDynamicin yet, so there's no caller to fix today.Public API changes
moq-net: new enum variantError::Unroutable(the enum is#[non_exhaustive], so additive). New wire code30.libmoqalready maps everymoq_net::Errorto a single-2status, so no FFI change is needed.Test plan
cargo test -p moq-net --lib(386 passed)cargo clippy -p moq-netcleandynamic_request_unroutable_without_handler(renamed) assertsUnroutabledynamic_request_handler_droppedassertsUnroutablefor both the pending future and a fresh requestdynamic_request_accept_after_handler_dropped(new) covers accept-after-drop(Written by Claude)
🤖 Generated with Claude Code
Generated by Claude Code