ws_stats.rs has two suppressions: run_collector (line 235) and handle_stats_socket (line 364), both #[allow(clippy::cognitive_complexity)].
What they do
run_collector (~65 lines) — streams container stats via docker.stats() in a loop, extracts CPU/mem/net/block values, pushes to history ring, broadcasts to subscribers, and handles cleanup only if this collector's broadcast sender is still the active one (guards against replacement collectors)
handle_stats_socket (~55 lines) — replays history buffer to a newly connected WebSocket client, then runs a tokio::select! loop relaying broadcast receiver output to the socket (nearly identical to ws_service_stats.rs and ws_host_service_stats.rs)
What to do
1. Extract stats chunk processing from run_collector
Lines 256–276 process a single stats chunk: extract values, lock history, push to ring, send via broadcast. Extract:
async fn process_stats_chunk(
state: &AppState,
key: &str,
stats: Stats,
prev_cpu_total: &mut u64,
prev_cpu_system: &mut u64,
tx: &broadcast::Sender<serde_json::Value>,
)
2. Extract collector cleanup guard
Lines 281–300 check whether this collector's broadcast sender is still the active one and only remove it if so. Extract:
async fn cleanup_collector_if_current(
state: &AppState,
key: &str,
tx: &broadcast::Sender<serde_json::Value>,
)
3. Extract history replay for handle_stats_socket
Lines 369–379 replay the history ring to the socket. Extract (shared with ws_service_stats.rs and ws_host_service_stats.rs):
async fn replay_stats_history(
socket: &mut WebSocket,
history: &Mutex<HashMap<String, VecDeque<serde_json::Value>>>,
key: &str,
) -> ControlFlow<()>
4. Extract broadcast forwarding loop
The tokio::select! loop that forwards broadcast messages to the socket. Shared across all three stats handlers:
async fn relay_broadcast_to_socket(
socket: &mut WebSocket,
rx: &mut broadcast::Receiver<serde_json::Value>,
key: &str,
)
5. Add unit tests
cleanup_collector_if_current:
- When tx matches current → removes entry
- When tx differs (replacement collector) → leaves entry
Important
The workspace Cargo.toml sets cognitive_complexity, too_many_lines, too_many_arguments, and several other clippy lints to warn globally. Run make lint after every change and make sure the output is clean. Don't fix a suppression here only to create new warnings elsewhere.
Acceptance criteria
Related
Tracking issue pattern from previous PRs: #122, #133, #157, #158, #171, #172, #173, #174, #175
ws_stats.rshas two suppressions:run_collector(line 235) andhandle_stats_socket(line 364), both#[allow(clippy::cognitive_complexity)].What they do
run_collector(~65 lines) — streams container stats viadocker.stats()in a loop, extracts CPU/mem/net/block values, pushes to history ring, broadcasts to subscribers, and handles cleanup only if this collector's broadcast sender is still the active one (guards against replacement collectors)handle_stats_socket(~55 lines) — replays history buffer to a newly connected WebSocket client, then runs atokio::select!loop relaying broadcast receiver output to the socket (nearly identical tows_service_stats.rsandws_host_service_stats.rs)What to do
1. Extract stats chunk processing from
run_collectorLines 256–276 process a single stats chunk: extract values, lock history, push to ring, send via broadcast. Extract:
2. Extract collector cleanup guard
Lines 281–300 check whether this collector's broadcast sender is still the active one and only remove it if so. Extract:
3. Extract history replay for
handle_stats_socketLines 369–379 replay the history ring to the socket. Extract (shared with
ws_service_stats.rsandws_host_service_stats.rs):4. Extract broadcast forwarding loop
The
tokio::select!loop that forwards broadcast messages to the socket. Shared across all three stats handlers:5. Add unit tests
cleanup_collector_if_current:Important
The workspace
Cargo.tomlsetscognitive_complexity,too_many_lines,too_many_arguments, and several other clippy lints towarnglobally. Runmake lintafter every change and make sure the output is clean. Don't fix a suppression here only to create new warnings elsewhere.Acceptance criteria
process_stats_chunkextracted (fromrun_collector)cleanup_collector_if_currentextracted with unit testsreplay_stats_historyextracted (shared with other stats handlers)relay_broadcast_to_socketextracted (shared)make test)make lintpasses with zero new warnings#[allow(clippy::cognitive_complexity)]suppressions ifmake lintpasses without them, keep any still needed (note why)Related
Tracking issue pattern from previous PRs: #122, #133, #157, #158, #171, #172, #173, #174, #175