mirror of
https://github.com/ruvnet/RuView.git
synced 2026-10-18 21:00:22 -05:00
/api/v1/stream/status returned "fps": 10 whenever tick > 1, whatever the real rate, and both it and /health counted every broadcast subscriber (recorder, MQTT bridge) as a client. The dashboard Streaming card read "IDLE, 0 client(s)" for up to 30 s while the page was streaming, because its first /health poll lands before the page's socket connects; with auth on, the ticket round-trip widens that gap. - New stream_stats module: UpdateRateMeter (sliding 5 s window, bounded at 1024 samples) and WsClientCounter with an RAII guard. - AppStateInner::advance_tick() replaces the five `s.tick += 1` sites and records each sensing update in the meter. - /api/v1/stream/status now returns the measured update rate as `fps` (0 when nothing flows), `active` from that rate, `clients` from the WebSocket counter, `nodes` with each fresh node's measured csi_fps (null until its EMA has 5 samples) and `csi_fps_total`. - /health and the /health/health stream component count WebSocket clients on /ws/sensing and /api/v1/stream/pose; the stream component also carries the measured rate. - DashboardTab re-reads health 500 ms after the sensing socket connects or drops, so the card follows the socket instead of waiting for the next 30 s poll. Fixes #2087 Co-Authored-By: claude-flow <ruv@ruv.net>