Skip to content

Refactor ws_stats.rs to reduce cognitive_complexity and add test coverage #218

@mukeshblackhat

Description

@mukeshblackhat

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

  • process_stats_chunk extracted (from run_collector)
  • cleanup_collector_if_current extracted with unit tests
  • replay_stats_history extracted (shared with other stats handlers)
  • relay_broadcast_to_socket extracted (shared)
  • Both functions use the new helpers
  • All tests pass (make test)
  • make lint passes with zero new warnings
  • Remove both #[allow(clippy::cognitive_complexity)] suppressions if make lint passes without them, keep any still needed (note why)

Related

Tracking issue pattern from previous PRs: #122, #133, #157, #158, #171, #172, #173, #174, #175

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions