Skip to content

moq-lite: add DATAGRAMS control stream + QUIC datagram delivery (Lite05)#1374

Draft
kixelated wants to merge 3 commits intomainfrom
datagrams
Draft

moq-lite: add DATAGRAMS control stream + QUIC datagram delivery (Lite05)#1374
kixelated wants to merge 3 commits intomainfrom
datagrams

Conversation

@kixelated
Copy link
Copy Markdown
Collaborator

Summary

  • New wire version Lite05 / DRAFT_05 (ALPN moq-lite-05, code 0xff0dad05) gating an opt-in unreliable delivery path.
  • New DATAGRAMS bidi control stream (0x6) parallel to SUBSCRIBE. Sharing the same subscribe_id namespace lets a single QUIC datagram body be routed by ID alone.
  • QUIC datagram body: subscribe_id (i) | sequence (i) | payload (b), payload capped at 1200 B. The sequence number is preserved on the wire (ignored by Lite05 semantics) so a future moq-transport adapter can reuse the same encoding.
  • 33 ms publisher-side cache; per-subscriber max_latency filters stale entries on forward. max_latency = 0 is strict: only fresh arrivals (no congestion-delayed retries).
  • Public API mirrors groups: TrackProducer.write_datagram / append_datagram, TrackConsumer.subscribe_datagramsDatagramsConsumer. JS exposes Track.writeDatagram / appendDatagram / recvDatagram / skipDatagramsToLatest.
  • Spec draft section + Lite05 changelog entry live in moq-drafts (separate repo).

Files

  • Rust: lite/datagram.rs (wire) and model/datagram.rs (model) added; model/track.rs, lite/publisher.rs, lite/subscriber.rs, version + ControlType enums updated.
  • TypeScript: lite/datagram.ts (wire) and datagram.ts (model) added; track.ts, lite/connection.ts, lite/publisher.ts, lite/subscriber.ts, version + StreamId updated.

Test plan

  • cd rs/moq-lite && cargo test (302 tests, 17 new)
  • cd js/lite && bun test (252 tests, 12 new)
  • just check clean across all crates and JS workspaces
  • Manual relay round-trip: two moq-lite-05 peers exchange datagrams via moq-relay; verify 33 ms cache eviction
  • Cross-version: Lite04Lite05 peer never opens a Datagrams stream and never sends/receives datagram bodies
  • Browser smoke: WebTransport.datagrams exercised in a watch demo against a Lite05 relay

Out of scope

  • Subscriber-configurable cache age (hardcoded 33 ms for now)
  • Chunked datagrams for payloads > 1200 B
  • moq-transport adapter that uses the sequence field for ordering / replay
  • Migrating hang / publish / watch layers to use datagrams

🤖 Generated with Claude Code

kixelated and others added 3 commits May 4, 2026 15:57
Adds an explicit, opt-in unreliable delivery path on Track, parallel to
groups, gated behind a new wire version Lite05 / DRAFT_05 (ALPN
moq-lite-05). Subscribers open a new DATAGRAMS bidi stream (0x6) for the
tracks they want; QUIC datagram bodies carry `subscribe_id | sequence |
payload`. Payload is capped at 1200 bytes and the publisher caches
~33 ms for late subscribers; each subscriber's `max_latency` filters
stale entries on forward (`0` is strict, no congestion-delayed retries).

Spec draft (datagrams section + Lite05 changelog) lives in moq-drafts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The default Versions::all() advertises moq-lite-05 in the ALPN list, but
the client/server match arms only handled up through moq-lite-04, so any
peer that picked moq-lite-05 would error with UnknownAlpn. Mirror the 04
arm for 05 in both Rust (client.rs/server.rs) and TypeScript
(connect.ts/accept.ts), and include ALPN_05 in the WebTransport protocols
list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves merge conflicts in version.rs, lite/subscriber.rs, and model/track.rs.

Renames the experimental wire version `Lite05` / `moq-lite-05` to
`Lite04Datagrams` / `moq-lite-04-datagrams` per request — this variant
will not be released as Draft05; it remains an experimental opt-in
DATAGRAMS extension on top of Draft04. Wire code 0xff0dad05 is left
unchanged for now since it only matters internally.

Drops the cascading-abort-to-groups loop added on this branch (per the
no-cascade rule for child handles); the parallel datagrams channel
abort/finish cascade is kept since it is internal to the same
TrackProducer, not a shared child entity.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant