Skip to content

moqx stats: multi-backend aggregation gap #569

Description

@afrind

The stats model assumes one QUIC backend (pico or mvfst) at a time. When both
listeners run simultaneously, their collectors both register with StatsRegistry
and aggregateAsync() sums their snapshots field-wise into the same StatsSnapshot
slots. There's no way to distinguish pico vs mvfst contributions in the output.

Affects all shared QUIC counter/histogram fields (quicPacketsSent, RTT
histograms, etc.).

Fix properly before adding per-backend fields — options:

  • Split snapshot slots by backend (STATS_PICO_* vs STATS_MVFST_*)
  • Add a backend= label at Prometheus export time (requires per-collector metadata)

There's a third stack now: ProxygenQmux. It deliberately registers no
QuicStatsCollector (qmux runs over TCP, not mvfst), so it doesn't pollute the
quic* counters. It does register EventBase collectors, which exposes a related
bug below.

Adjacent bug: EVB collector double-registration

Same root cause — one shared registry and one shared ioExecutor across all
listeners. MoqxRelayServer and MoqxQmuxRelayServer each loop over every EVB in
the shared ioExecutor and create an EventBaseStatsCollector for it. Configure
two such listeners and each shared EVB ends up with two collectors: both land in
the registry's collector list (which never dedups), but setObserver() and the
EventBaseLocal entry each keep only the last one. The orphaned collector stays
in the aggregation list contributing zeros, and findEvbCollector only ever
resolves to the survivor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    Low

    Severity

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions