feat(net)!: extract stats publishing into moq-stats with compressed tracks#2380
Merged
Conversation
…racks moq_net::stats is now collection-only: Producer becomes Registry, the publishing task moves to the new moq-stats crate, and every stats track gains a DEFLATE-compressed .json.z sibling encoded via moq-json. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Sorry @kixelated, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
Registry::new took a bare Option<PathOwned> exclude prefix, which was a future breaking change waiting to happen. It now takes a non_exhaustive stats::Config (new() + with_exclude), and exclude generalizes to a list of prefixes while we are at it. Also gives the moq_json snapshot configs the same with_* builder setters the stream module already has, and moq_stats::ConsumerConfig a matching new() + with_compression, replacing default-then-field-set at the call sites (and a clippy field_reassign_with_default warning in a test). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ompression-d2b7a6
The main-into-dev merge (fe9b782) left a double blank line in moq-ffi's error enum, so cargo fmt --check fails on every PR merge ref targeting dev. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kixelated
enabled auto-merge (squash)
July 18, 2026 02:53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Splits
moq_net::statsinto collection and publication, and adds compressed stats tracks:moq_net::statsis now collection-only.Produceris renamedRegistry(Registry::new(exclude)/Registry::disabled()); the publishing task,Config, and frame types are gone from moq-net. The three duplicated counter shapes (RawCounts,TrafficTotals,BroadcastFrame) merge into one serde-both-waysTraffictype, and (SessionTotals,SessionFrame) intoPresence, so the wire shape and the rollup are the same type. A newRegistry::report()returns the per-(broadcast, tier)detail and prunes dead entries (the GC that used to live in the task);snapshot()is unchanged and never prunes.rs/moq-statscrate (depends on moq-net + moq-json), with both halves:Producerbuilds the registry itself (the config prefix is wired as the registry's exclude prefix, so the stats-of-stats cycle break can't be misconfigured) and drains it on an interval. Each track is now a pair: the plain.jsontrack is written throughmoq_json::snapshotwithdelta_ratio: 0, compression: false, which is wire-identical to the old hand-rolled output (one full JSON object per single-frame group, same field order); the new.json.zsibling uses merge-patch deltas inside a group-shared DEFLATE window, which is a fraction of the bytes since successive frames are nearly identical.Consumeryields typedTrafficFrame/SessionsFrameoff either flavor (ConsumerConfig { compression }), plusparse_node_path(prefix, depth, path)andtraffic_track/sessions_tracknaming helpers, so downstream aggregators (e.g. the moq.pro dash/edge slurp) stop hand-duplicating the wire types, track tables, and announce-path parsing.Cluster.statsis now theRegistry;StatsConfig::buildreturns themoq_stats::Producer, whichmain.rskeeps alive for the run. No config surface changes.Why
The stats frames are cumulative counter maps that barely change tick to tick: the best possible case for merge-patch deltas + a shared compression window, which
moq-jsonalready implements forcatalog.json.z. moq-json depends on moq-net, so moq-net could not use it directly; splitting publication out of moq-net (which only collects now) fixes the dependency direction and deletes a hand-rolled subset of moq-json in the process (net -760 lines before the new consumer half).Compatibility
.jsontracks are byte-compatible with the old output;.json.zsiblings are additive. Existing consumers keep working unchanged.pubchanges are confined tomoq_net::stats(rename + type merge) andmoq-relay'sCluster::with_statssignature, hence thedevtarget.Cross-package sync
catalog.json.z).getStats()calls); a@moq/statsconsumer can follow up if needed.doc/bin/relay/config.mdstats section documents the.zsiblings;rs/CLAUDE.mdcrate map updated.Testing
report()'s prune-after-final-values contract plus serde forward/backward compat forTraffic..json.zflavors decode to identical frames across an update (exercising the delta path).just checkandRUSTDOCFLAGS="-D warnings" cargo docpass.🤖 Generated with Claude Code