Skip to content

Integrate time and delivery into model + update protocol layer - #826

Closed
kixelated wants to merge 1 commit into
delivery-expirationfrom
model-refactoring
Closed

Integrate time and delivery into model + update protocol layer#826
kixelated wants to merge 1 commit into
delivery-expirationfrom
model-refactoring

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Summary

This PR combines the model refactoring with protocol layer updates (originally planned as separate PRs #3 and #4, but they're too tightly coupled to separate). The model now supports temporal awareness and latency-aware delivery, and the protocol layer is updated to support the new subscribe parameters.

Rust (moq-lite) Model Changes

Frame

  • Added instant: Time field for presentation timestamp
  • Frame size changed from u64 to usize
  • State machine now tracks time alongside data

Group

  • Integrates with ExpiresProducer for expiration tracking
  • Calls expires.create_frame() when appending frames
  • Tracks max_instant for latest timestamp in group

Track (Major Refactoring)

TrackProducer now internally manages:

  • delivery: DeliveryProducer - for updating track-level delivery preferences
  • subscribers: Subscribers - tracks all connected consumers and their demands
  • expires: ExpiresProducer - manages group/frame expiration

TrackConsumer now has:

  • subscriber: Subscriber - declares its own delivery preferences
  • expires: ExpiresConsumer - can check if groups are expired
  • delivery: DeliveryConsumer - can react to delivery changes
  • Filters expired groups transparently before returning them

Breaking change: Priority removed from Track, now per-subscriber via Delivery

Broadcast

  • Simplified from ~450 to ~200 lines
  • Stores TrackProducer instead of TrackConsumer
  • Separates explicit publishes (producers) from dynamic requests (requested)
  • Cleaner ownership model

Rust (moq-lite) Protocol Layer Changes

IETF Protocol

  • Added delivery_timeout parameter to Subscribe and Publish messages
  • Added group_order field to SubscribeOk
  • Renamed parameter methods: get_int/set_intget_varint/set_varint
  • Added Default derive for RequestId

Lite Protocol

  • Added DRAFT_03 version
  • Added max_latency and ordered fields to Subscribe/SubscribeOk/SubscribeUpdate
  • New lite/frame.rs for frame encoding with timestamp deltas
  • Version-gated: Draft01/Draft02 still work, Draft03 adds new fields

TypeScript (lite) Changes

Core Types

  • New Frame class with instant: Time.Milli and payload: Uint8Array
  • Tracks now have reactive properties using Signals:
    • priority: Signal<number>
    • maxLatency: Signal<Time.Milli>
    • ordered: Signal<boolean>
  • Groups and Broadcasts updated to work with new Frame type

Protocol Layer

  • Added DRAFT_03 version matching Rust
  • Subscribe messages now include maxLatency and ordered fields
  • Frame encoding with delta timestamps
  • Version-gated protocol changes
  • Reactive updates: when track properties change, SubscribeUpdate messages are sent

Signals

  • Added Signal utilities for reactive track properties
  • Enables dynamic priority/latency negotiation mid-stream

Breaking Changes

⚠️ Track API: priority removed from Track, now per-subscriber via Delivery
⚠️ Frame size: Changed from u64 to usize in Rust
⚠️ Frame type: TypeScript now uses Frame objects instead of raw Uint8Array
⚠️ Subscribe API: Now requires Delivery parameter

Compatibility

Version gating: Draft01/Draft02 clients continue to work
Draft03: New version includes max_latency and ordered fields
Backward compatible: Older versions negotiate down gracefully

Known Issues

Test Plan

Dependencies

Notes

Originally planned as two separate PRs (Model Refactoring + Protocol Layer), but they're too tightly coupled:

  • Model changes require protocol support for new fields
  • Protocol changes are meaningless without model integration
  • Splitting them creates non-compiling intermediate states

This combined PR ensures the model and protocol stay synchronized.

🤖 Generated with Claude Code

This PR combines the model refactoring with protocol layer updates since they're tightly coupled. The model now supports temporal awareness and latency-aware delivery.

## Rust (moq-lite) Model Changes

**Frame (`model/frame.rs`)**:
- Added `instant: Time` field for presentation timestamp
- Frame size changed from `u64` to `usize`
- State machine now tracks time alongside data

**Group (`model/group.rs`)**:
- Integrates with `ExpiresProducer` for expiration tracking
- Calls `expires.create_frame()` when appending frames
- Tracks `max_instant` for latest timestamp in group

**Track (`model/track.rs`)**:
- Major refactoring: `TrackProducer` now manages:
  - `delivery: DeliveryProducer` for delivery preferences
  - `subscribers: Subscribers` tracking all consumers
  - `expires: ExpiresProducer` for group/frame expiration
- `TrackConsumer` now has:
  - `subscriber: Subscriber` with its own delivery preferences
  - `expires: ExpiresConsumer` to check expiration
  - `delivery: DeliveryConsumer` to react to changes
- Filters expired groups transparently before returning
- **Breaking change**: Track no longer has `priority` field (moved to per-subscriber `Delivery`)

**Broadcast (`model/broadcast.rs`)**:
- Simplified from ~450 to ~200 lines
- Stores `TrackProducer` instead of `TrackConsumer`
- Separates explicit publishes (`producers`) from dynamic requests (`requested`)
- Cleaner ownership model

**Origin (`model/origin.rs`)**:
- API consistency improvements
- Uses `.new()` instead of `.default()`
- Updated tests for new producer/consumer patterns

## Rust (moq-lite) Protocol Layer Changes

**IETF Protocol**:
- `subscribe.rs`: Added `delivery_timeout` parameter (maps to `max_latency`)
- `publish.rs`: Added `delivery_timeout` parameter
- `publisher.rs` & `subscriber.rs`: Handle new delivery fields
- `parameters.rs`: Renamed `get_int`/`set_int` to `get_varint`/`set_varint`
- `request.rs`: Added `Default` derive for `RequestId`
- `setup.rs`: Updated to use new parameter methods

**Lite Protocol**:
- `version.rs`: Added `DRAFT_03` version
- `subscribe.rs`: Added `max_latency` and `ordered` fields to Subscribe/SubscribeOk/SubscribeUpdate
- `frame.rs` (new): Frame encoding helper with timestamp deltas
- `publisher.rs` & `subscriber.rs`: Encode/decode new fields, version-gated for Draft03
- `session.rs`: Updated for new parameter APIs
- `mod.rs`: Export `FrameHeader`

**Coding Layer**:
- `reader.rs` & `writer.rs`: Updated for varint parameter changes

## TypeScript (lite) Changes

**Core Types**:
- `frame.ts` (new): `Frame` class with `instant: Time.Milli` and `payload: Uint8Array`
- `track.ts`: Tracks now have reactive `priority`, `maxLatency`, and `ordered` properties using Signals
- `group.ts`: Updated to work with Frame objects
- `broadcast.ts`: Simplified track management matching Rust changes
- `stream.ts`: Updated for new Frame type

**Protocol Layer**:
- `lite/version.ts`: Added `DRAFT_03`
- `lite/subscribe.ts`: Added `maxLatency` and `ordered` fields to messages
- `lite/frame.ts` (new): Frame encoding with delta timestamps
- `lite/publisher.ts` & `lite/subscriber.ts`: Handle new fields with version gating
- `lite/session.ts`, `lite/connection.ts`: Updated for new APIs
- `ietf/publisher.ts` & `ietf/subscriber.ts`: Updated for new delivery parameters
- `connection/connect.ts`: Use DRAFT_03 by default
- `connection/reload.ts`: Handle new track properties

**Signals**:
- `js/signals/src/index.ts`: Added Signal utilities for reactive track properties

**Validation**:
- `zod.ts`: Added validation for new fields

## Breaking Changes

- **Track API**: `priority` removed from Track, now per-subscriber via `Delivery`
- **Frame size**: Changed from `u64` to `usize` in Rust
- **Frame type**: TypeScript now uses `Frame` objects instead of raw `Uint8Array`
- **Subscribe API**: Now requires `Delivery` parameter

## Compatibility

- **Version gating**: Draft01/Draft02 clients continue to work
- **Draft03**: New version includes `max_latency` and `ordered` fields
- **Backward compatible**: Older versions negotiate down gracefully

## Known Issues

- hang crate and related examples will fail to compile (fixed in next PR)
- moq-relay and moq-clock need updates (fixed in later PR)

## Dependencies

- **Depends on**: PR #2 (Delivery & Expiration)
- **Depended on by**: PR #5 (Hang Simplification)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@kixelated kixelated closed this Jan 10, 2026
@kixelated
kixelated deleted the model-refactoring branch June 26, 2026 21:58
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