Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions nix/moxygen-track-status.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
--- a/moxygen/MoQFramer.cpp
+++ b/moxygen/MoQFramer.cpp
@@ -3362,10 +3362,9 @@ RequestOk RequestOk::fromTrackStatusOk(const TrackStatusOk& trackStatusOk) {
folly::to_underlying(TrackRequestParamKey::EXPIRES),
static_cast<uint64_t>(trackStatusOk.expires.count()));

- // Add group order parameter
- requestOk.requestSpecificParams.emplace_back(
- folly::to_underlying(TrackRequestParamKey::GROUP_ORDER),
- folly::to_underlying(trackStatusOk.groupOrder));
+ // No GROUP_ORDER: it is only a SUBSCRIBE, PUBLISH_OK or FETCH parameter,
+ // and the receiver closes the session on it anywhere else. As in
+ // SUBSCRIBE_OK, a publisher's group order is a track property.

// Add the LARGEST_OBJECT param if present
if (trackStatusOk.largest) {
--- a/moxygen/moqtest/MoQTestPublisher.cpp
+++ b/moxygen/moqtest/MoQTestPublisher.cpp
@@ -88,18 +88,25 @@ void MoQTestPublisher::cancelAll() {
}
}

-std::shared_ptr<MoQForwarder> MoQTestPublisher::makeForwarder(
- const FullTrackName& ftn,
- uint64_t /*version*/) {
- auto forwarder = std::make_shared<MoQForwarder>(ftn);
+namespace {

- // Advertise the priority even-numbered groups are published at, so the
- // subgroup and datagram encodings elide it for those and write it
- // explicitly for the odd ones.
+// Advertise the priority even-numbered groups are published at, so the
+// subgroup and datagram encodings elide it for those and write it explicitly
+// for the odd ones.
+Extensions makeTrackProperties() {
Extensions trackProperties;
trackProperties.insertMutableExtension(
Extension{kPublisherPriorityExtensionType, kMoQTestPublisherPriority});
- forwarder->setExtensions(std::move(trackProperties));
+ return trackProperties;
+}
+
+} // namespace
+
+std::shared_ptr<MoQForwarder> MoQTestPublisher::makeForwarder(
+ const FullTrackName& ftn,
+ uint64_t /*version*/) {
+ auto forwarder = std::make_shared<MoQForwarder>(ftn);
+ forwarder->setExtensions(makeTrackProperties());

auto cb = std::make_shared<TrackCallback>();
cb->publisher = shared_from_this();
@@ -121,6 +128,34 @@ void MoQTestPublisher::retireTrack(
tracks_.erase(it);
}

+folly::coro::Task<Publisher::TrackStatusResult> MoQTestPublisher::trackStatus(
+ TrackStatus trackStatus) {
+ XLOG(INFO) << "Received Track Status";
+
+ auto res = moxygen::convertTrackNamespaceToMoqTestParam(
+ &trackStatus.fullTrackName.trackNamespace);
+ if (res.hasError()) {
+ co_return folly::makeUnexpected(
+ TrackStatusError{
+ trackStatus.requestID,
+ TrackStatusErrorCode::NOT_SUPPORTED,
+ "Invalid Parameters"});
+ }
+
+ TrackStatusOk ok;
+ ok.requestID = trackStatus.requestID;
+ auto trackIt = tracks_.find(trackStatus.fullTrackName);
+ if (trackIt == tracks_.end()) {
+ ok.trackProperties = makeTrackProperties();
+ co_return ok;
+ }
+ const auto& forwarder = trackIt->second.forwarder;
+ ok.groupOrder = forwarder->groupOrder();
+ ok.largest = forwarder->largest();
+ ok.trackProperties = forwarder->extensions();
+ co_return ok;
+}
+
folly::coro::Task<MoQSession::SubscribeResult> MoQTestPublisher::subscribe(
SubscribeRequest sub,
std::shared_ptr<TrackConsumer> callback) {
--- a/moxygen/moqtest/MoQTestPublisher.h
+++ b/moxygen/moqtest/MoQTestPublisher.h
@@ -71,6 +71,11 @@ class MoQTestPublisher : public Publisher,
// ask for data -- otherwise it would hold the session open forever.
void cancelAll();

+ // Answers with what a SUBSCRIBE_OK for the track would carry, without
+ // starting it. A track that is not being generated has no largest location.
+ virtual folly::coro::Task<TrackStatusResult> trackStatus(
+ TrackStatus trackStatus) override;
+
// Subscribing Methods. Subscribers to the same track share one forwarder
// and one generator, so a late subscriber joins the track in progress.
virtual folly::coro::Task<SubscribeResult> subscribe(
13 changes: 10 additions & 3 deletions nix/moxygen.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@ stdenv.mkDerivation {
version = "unstable-2026-10-23";
src = sources.moxygen;
cmakeDir = "../standalone";
# The relay conformance profile: the client accepts track-level priority and
# an END_OF_TRACK directly after the last object. Every other check stays.
patches = [ ./moxygen-profile.patch ];
patches = [
# The relay conformance profile: the client accepts track-level priority and
# an END_OF_TRACK directly after the last object. Every other check stays.
./moxygen-profile.patch
# The test origin answers TRACK_STATUS, which a relay cluster's edge sends
# before subscribing, without the GROUP_ORDER parameter draft-18 forbids in
# TRACK_STATUS_OK. Drop at the next pin bump once
# https://github.com/facebookexperimental/moxygen/pull/264 lands.
./moxygen-track-status.patch
];
nativeBuildInputs = [
cmake
ninja
Expand Down
1 change: 0 additions & 1 deletion quest/m1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ Catalog HLS field.
- [Routing guide](/quest/m1/routing-guide.md) - concepts and practical outbound federation setup
- [Generated C bindings](/quest/m1/c/README.md) - C generated from moq-ffi ships as `moq-c` 0.8.0 and replaces the hand-written libmoq
- [Exact timestamps in every binding](/quest/m1/binding-timestamps.md) - bindings carry `{value, scale}` timestamps instead of lossy microseconds
- [moq-transport passthrough](/quest/m1/ietf-extension/README.md) - object IDs, properties, end status, datagram objects, and unknown track properties survive moq-transport -> moq-relay (and a relay cluster) -> moq-transport; moxygen's moq-test sections 1-7 pass nightly under the relay conformance profile, except cases that use a subgroup other than 0
- [Announcement takeover](/quest/m1/announce-takeover.md) - a new independent route explicitly continues instances served through its predecessor, with shared Rust/JS semantics and lite-07 wire
- [Subscribe ranges](/quest/m1/subscribe-ranges/README.md) - a lite-07 SUBSCRIBE asks for past and live ranges with absolute or relative ends, in either order, and replaces FETCH; merged ranges never starve a subscriber; relays fill misses by range, including over moq-transport
- [A widened max age re-offers cached groups](/quest/m1/resolved-demand.md) - a warm relay serves a reader with a wider max age the cached groups a cold relay would, with no wire change
Expand Down
3 changes: 1 addition & 2 deletions quest/m1/api-audit/model-private.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ for a named consumer.
`Track.Producer.dropGroups` become internal again (`dropGroups` returns to
`hooks.dropTrackGroups`). Keep `create_frame(self)`: hang and moq-mux use it.
- The `// pending:` and `// private:` marks and their lint are already gone.
The moq-transport passthrough exception stays documented in
[moq-transport passthrough](/quest/m1/ietf-extension/README.md).
The moq-transport passthrough fields stay crate-private.

Rejected: the toy-transport integration tests proving a third party could
build from the public model; the goal they proved is dropped.
Expand Down
133 changes: 0 additions & 133 deletions quest/m1/ietf-extension/README.md

This file was deleted.

1 change: 0 additions & 1 deletion quest/m1/interop-coverage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,3 @@ coverage on `main` at `3ab6cbf81d`.

- [Runner client bump](/quest/m2/release/runner-client-bump.md) - after the cut publishes #5083, the runner's Rust client stops stamping every object
- [Interop audit](/quest/m2/audit-interop.md) - classifies the red cells these cases produce
- [moq-transport passthrough](/quest/m1/ietf-extension/README.md) - Moxygen's moq-test conformance through moq-relay
4 changes: 0 additions & 4 deletions quest/m1/smoke-moxygen.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,3 @@ Reported upstream as
acknowledged 2026-10-16; check it and the Smoke job. The fix is a registered default
(Largest Object or Next Group Start) for drafts that lack LargestGroup.
Do not accept 0xFA in moq-relay.

## Related

- [moq-transport passthrough](/quest/m1/ietf-extension/README.md) - broader object forwarding and moq-test conformance
43 changes: 31 additions & 12 deletions test/ietf-conformance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ builds the Moxygen revision and matching Meta dependencies pinned in
`conformance_test.sh` through this checkout's relay. This is separate from the
published-package smoke matrix.

Sections 1-7 run on both shared drafts, 16 and 18, through one relay. Each cell
Sections 1-7 run on both shared drafts, 16 and 18, through one relay, and on
draft 18 through a two-relay cluster joined by native lite-07. Draft 16 has no
cluster cell: its TRACK\_STATUS\_OK has no Track Properties block, so the
cluster's origin cannot learn the track's priority from it. Each cell
runs 29 upstream SUBSCRIBE cases. A direct-origin control runs the same cases
once per draft, separating suite or pin failures from relay behavior. FETCH is
skipped using upstream's `SKIP_FETCH`; section 8 uses PUBLISH and is outside the
Expand Down Expand Up @@ -53,16 +56,32 @@ Every other check is upstream's: forwarded object IDs, properties, payloads,
END\_OF\_GROUP status objects and header bits, and FIRST\_OBJECT. Any other
priority, a second END\_OF\_TRACK, or one anywhere else still fails.

Measured over six consecutive runs:
Measured over three consecutive runs, after six earlier runs of the
direct-origin and one-relay cells:

| Draft | Direct origin | One relay |
| --- | --- | --- |
| 16 | 29 pass | 29 pass |
| 18 | 29 pass | 29 pass |
| Draft | Direct origin | One relay | Two relays |
| --- | --- | --- | --- |
| 16 | 29 pass | 29 pass | not run |
| 18 | 29 pass | 29 pass | 29 pass |

A two-relay cell is not run yet. The edge needs metadata from TRACK\_STATUS
before subscribing, and the pinned MoQTestPublisher inherits NOT\_SUPPORTED for
that request, so every case fails before media. The relay preserves that
refusal, rather than widening query-only demand into SUBSCRIBE. The
[passthrough quest](../../quest/m1/ietf-extension/README.md) tracks adding the
cell back once a pinned publisher answers it.
## Local Moxygen patches

A cluster's edge asks the origin about a track with TRACK\_STATUS before
subscribing.
[`nix/moxygen-track-status.patch`](../../nix/moxygen-track-status.patch) makes
the pinned MoQTestPublisher answer it with what its SUBSCRIBE\_OK carries,
instead of NOT\_SUPPORTED, and stops Moxygen writing a GROUP\_ORDER parameter
in TRACK\_STATUS\_OK, which draft 18 forbids there. Drop it at the next pin
bump once
[facebookexperimental/moxygen#264](https://github.com/facebookexperimental/moxygen/pull/264)
is in the pinned revision.

## Known verifier flake

One early run of the direct draft-18 control failed upstream's "Large scale:
Many groups and objects" with `Group Mismatch: Actual=1 Expected=0`, without
any relay. It has not recurred since. The verifier keeps one cursor per
subscription and expects groups in order, although each group arrives on its
own stream; its own comment calls that a spurious failure. If it recurs in
nightly, fix the verifier in the profile patch with per-group cursors rather
than retrying.
Loading
Loading