Skip to content

feat(moq-net,moq-cli): per-track stats + moq-cli --stats usage display#1671

Open
kixelated wants to merge 1 commit into
devfrom
claude/moq-cli-stats
Open

feat(moq-net,moq-cli): per-track stats + moq-cli --stats usage display#1671
kixelated wants to merge 1 commit into
devfrom
claude/moq-cli-stats

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Summary

Adds a live usage display to moq-cli and makes the moq-net stats per-track to back it. Run any transfer with --stats to see which tracks are being produced/consumed and a continuously rewritten upload/download table:

track                  rate        total    frames    groups
test.hang         24.3 KB/s      99.4 KB       129         6
  0.avc3          24.3 KB/s      99.2 KB       128         5
  catalog.json        0 B/s        162 B         1         1

The stats system was broadcast-scoped and only exposed via a published .stats broadcast. This makes it per-track and adds an in-process read API so a CLI can render it directly.

Broadcast totals stay O(1) to read. The existing broadcast-level Counters rollup is kept in sync on every bump, so reading a total is a single atomic load and never iterates the per-track map. The per-track maps are only walked when someone actually wants the per-track view (the snapshot task once per tick, or a snapshot() call).

moq-net

  • Add TrackCounters + per-(side, tier) track maps on BroadcastEntry. The track guards (PublisherTrack / SubscriberTrack) now bump both the broadcast rollup and the track's own atomics.
  • Add Stats::snapshot() -> StatsSnapshot (plus public BroadcastSnapshot / SideSnapshot / TrackCounts / SessionCounts) for in-process consumers. No broadcast subscription required.
  • The published per-broadcast JSON gains an additive tracks object; the wire frame now reuses SideSnapshot rather than a duplicate struct. Tier::idx is now public since the snapshot arrays are tier-indexed.
  • Dead tracks are GC'd in the snapshot task once their last subscription closes; their bytes remain counted in the rollup.

moq-cli

  • --stats / --stats-interval flags on publish, subscribe, serve, accept.
  • Builds an enabled aggregator (throwaway origin), attaches the tier handle via with_stats, and a render loop diffs successive snapshot()s to compute rates and repaints a per-track table on stderr (stdout stays clean for piped media). A process is single-direction, so the table just shows the active broadcast/track totals.

Docs

  • doc/bin/relay/config.md: document the new tracks field in the stats JSON.
  • doc/bin/cli.md: document --stats.

Cross-package sync

The moq-net wire/API row points at js/net + doc/concept. There's no JS stats aggregator to mirror; the per-broadcast stats JSON is a relay-internal feature (consumed by dashboards), and its format change is additive and documented in doc/bin/relay. No peer wire-protocol change.

Test plan

  • moq-net unit tests pass (374), including 3 new ones: per-track rollup, closed-track GC keeps rollup, no-op aggregator snapshot is empty.
  • cargo fmt + clippy clean (via nix); moq-relay / moq-native still build.
  • Manual end-to-end: ffmpeg | moq-cli serve + moq-cli subscribe --stats over QUIC renders the per-track table with live rates.

(Written by Claude)

Make moq-net stats per-track and surface them as a live usage table in
moq-cli. A broadcast total stays O(1) to read: the existing broadcast-level
`Counters` rollup is kept in sync on every bump, so reading a total never
iterates the per-track map.

moq-net:
- Add `TrackCounters` and per-(side,tier) track maps on `BroadcastEntry`. The
  track guards bump both the broadcast rollup and the track's own atomics.
- Add `Stats::snapshot() -> StatsSnapshot` (+ public `BroadcastSnapshot` /
  `SideSnapshot` / `TrackCounts` / `SessionCounts`) so an in-process consumer
  reads counters directly instead of subscribing to the `.stats` broadcast.
- The published per-broadcast JSON gains an additive `tracks` object; the wire
  frame now reuses `SideSnapshot` instead of a separate struct. `Tier::idx` is
  public since the snapshot arrays are tier-indexed.
- Dead tracks are GC'd in the snapshot task; their bytes remain in the rollup.

moq-cli:
- Add `--stats` / `--stats-interval` to publish/subscribe/serve/accept. Builds
  an enabled aggregator (throwaway origin), attaches the tier handle via
  `with_stats`, and repaints a per-track table on stderr each interval, with
  rates derived from successive snapshots. stdout stays clean for piped media.

docs: document the `tracks` field in doc/bin/relay/config.md and the `--stats`
flag in doc/bin/cli.md.

Co-Authored-By: Claude Opus 4.8 (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