Skip to main content

inspector_analysis/
task_growth.rs

1//! Task-growth rule: distinguishes leaks/contention pile-up from plain slowness.
2use inspector_core::{Diagnosis, FindingStatus, Snapshot};
3
4pub const GROWTH_THRESHOLD: i64 = 50;
5
6pub fn detect_task_growth(
7    base: &Snapshot,
8    current: &Snapshot,
9    base_id: &str,
10    current_id: &str,
11) -> Diagnosis {
12    let evidence = vec![base_id.to_string(), current_id.to_string()];
13    match (base.overview.active_tasks, current.overview.active_tasks) {
14        (Some(b), Some(c)) => {
15            let growth = c as i64 - b as i64;
16            if growth >= GROWTH_THRESHOLD {
17                Diagnosis {
18                    status: FindingStatus::Hypothesis,
19                    finding: format!("active tasks grew {b} -> {c} (+{growth})"),
20                    hypothesis: Some(
21                        "growth may indicate spawn leak or contention pile-up; correlate with scheduled-time".into(),
22                    ),
23                    confidence: 0.65,
24                    evidence,
25                    verification: Some(
26                        "capture task list sorted by polls; check for unbounded spawners".into(),
27                    ),
28                }
29            } else {
30                Diagnosis {
31                    status: FindingStatus::NoIssue,
32                    finding: format!("task count stable ({b} -> {c})"),
33                    hypothesis: None,
34                    confidence: 0.85,
35                    evidence,
36                    verification: None,
37                }
38            }
39        }
40        _ => Diagnosis {
41            status: FindingStatus::Observed,
42            finding: "task counts unavailable; no growth verdict".into(),
43            hypothesis: None,
44            confidence: 0.3,
45            evidence,
46            verification: Some("check completeness.missing_fields".into()),
47        },
48    }
49}