feat(moq-ffi): expose broadcast hop chain on announcements#1888
Conversation
Add MoqAnnouncement::hops() returning the broadcast's origin-id hop chain (oldest first) as Vec<u64>, surfaced through the Python moq wrapper as the Announcement.hops property (list[int]). Lets consumers inspect the relay path a broadcast traversed, e.g. for edge-affinity routing. Bump moq-rs to 0.3.1 to republish the wrapper with the new property. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
moq-ffi 0.2.24 is the first release carrying MoqAnnouncement::hops(). Tighten the moq-rs dependency floor to moq-ffi ~= 0.2.24 so the Announcement.hops property can't resolve against a moq-ffi that lacks hops(). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (6)
WalkthroughA new 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
Resolved conflicts across the moq-net frame/group rewrite (mandatory timestamps), moq-json (DEFLATE compression x timestamp API), moq-mux (rewind detection x duration-skip), the moqsink direct-write rewrite, and the JS API renames. #1888 (broadcast hop chain on announcements) was carried through: dev already plumbs hops onto BroadcastInfo from the wire announce, so moq-ffi reads them via broadcast.info().hops (main read the field directly as broadcast.hops). The Python wrapper, docs, and test came in unchanged. #1886 (untyped catalog extensions) was deferred rather than half-integrated: it conflicts with dev's CatalogExt/Producer<E> model and the importer refactor. Reverted its moq-mux/libmoq/moq-ffi pieces to dev's shape; the released version bumps + CHANGELOG entries (libmoq 0.3.8, moq-mux 0.6.0, moq-video 0.0.5) were kept. The dev port is owed as a follow-up. Also boxed moq-mux SourceState::Active (the merged Consumer grew past the large_enum_variant threshold) and routed empty-init avc3 past detect_avc1 so the rewritten moqsink h264 path works. Verified: cargo build + clippy --all-features -D warnings + tests across touched crates; JS typecheck + biome + tests; taplo/rustfmt clean.
Summary
Adds a way to read a broadcast's relay hop chain from an announcement, surfaced through the Python
moqpackage.rs/moq-ffi:MoqAnnouncement::hops() -> Vec<u64>returns the broadcast's origin-id hop chain, oldest first. The ids are read from the subscribed broadcast (BroadcastConsumerderefs toBroadcast, whosehops: OriginListis populated from the wireAnnounce). The announce itself (OriginAnnounce = (PathOwned, Option<BroadcastConsumer>)) doesn't carry hops, so they're captured off the broadcast at construction.py/moq-rs: newAnnouncement.hops -> list[int]property mirroringpath/broadcast.Vec<u64>maps tolist[int]via uniffi.doc/lib/py/moq-rs.md: documentsannouncement.hopsin the discovery section (Cross-Package Sync).Why
A downstream voice-agent worker self-elects which relay edge answers a client by inspecting the hop chain (counting how many hops share the fleet's internal-relay prefix). The Python
Announcementpreviously exposed only.pathand.broadcast, so the worker couldn't see hops. The worker reads it asgetattr(ann, "hops", None), so the property is namedhopsand returns alist[int]of u64 origin ids, oldest first.Release / versioning
This rides the next
moq-rsrelease, so the version bumps are included:moq-ffi0.2.23->0.2.24(the first release carryinghops()). This is exactly the patch release-plz would compute from an additivefeat, so it should reconcile and generate the0.2.24CHANGELOG on merge.moq-ffi's deps are all at versions already published in chore: release #1795, so there's no stale-dependency hazard.moq-rs0.3.0->0.3.1(republishes the wrapper;0.3.0is already on PyPI andrelease-py.ymlgates on the registry).moq-rsdependency floor tightenedmoq-ffi ~= 0.2.16->~= 0.2.24so theAnnouncement.hopsproperty can't resolve against amoq-ffithat lackshops().Cross-Package Sync
swift/kt/gogethops()automatically — they're uniffi-generated frommoq-ffiand re-mirrored on the nextmoq-ffi-v*tag, no manual edit.rs/libmoq(hand-written C API) intentionally left out of scope to keep this minimal and Python-focused; the Cmoq_announcedstruct can grow a hops accessor as a follow-up if a C consumer needs it.Test plan
cargo check -p moq-ffi/cargo clippy -p moq-fficlean (moq-ffi v0.2.24).just py check: ruff + format + pyright (0 errors); the tightened~= 0.2.24floor resolves against the workspacemoq-ffi 0.2.24.just py test: 38 passed, including the newtest_announcement_hops_over_wire(Server + Client over loopback TLS).ann.hopsreturns[1840552095890056]— alistofint;getattr(ann, "hops", None)returns it.Note: fmt/clippy ran on the system toolchain (
rustfmt 1.9.0) since the nix dev shell can't be entered in this environment; flag for CI's pinned toolchain.(Written by Claude)