fix(kanban): stall-veto CPU probe measures CPU burned NOW, not Linux lifetime pcpu (t_46a2f8a1) - #1038
fix(kanban): stall-veto CPU probe measures CPU burned NOW, not Linux lifetime pcpu (t_46a2f8a1)#1038Kyzcreig wants to merge 1 commit into
Conversation
…lifetime pcpu (t_46a2f8a1) _worker_cpu_active read `ps -o pcpu`. On Linux (procps) that is lifetime CPU time / lifetime elapsed, so any worker that ever did real work read nonzero for hours after stalling and vetoed its own reclaim: detect_progress_stalls could not reclaim a stalled worker on a Linux host. Measured on ACE-AI: a child that burned 2s then blocked read 66.4 -> 9.4 pcpu over 3-21s of pure idleness while its CPU-time delta was 0.000s. The same bias is the CI flake: a slow-starting test child could not decay below 0.1% within _wait_idle's 30s on a loaded runner. The probe now takes two psutil cpu_times() samples _CPU_SAMPLE_SECONDS apart and vetoes only on a positive user+system delta. Exited/zombie -> idle; psutil missing / AccessDenied / any probe error -> True (never authorizes a kill), as before. Tests: regression test for past-burn-then-idle; exited-process reads idle; probe-failure matrix moved from subprocess.run to psutil (AccessDenied, OSError, RuntimeError, psutil missing); _wait_idle streak 6->3 over delta samples; autouse fixture shortens the real sample window to 100ms.
|
Linux verification on ACE-AI at head 08ecc92. The host was already loaded by its CI runners (load1 about 45-72); this test generated no extra load. Interpreter: py3.11.15, psutil 7.2.2.
Raw bias measurement (a child burns 2 s, then blocks):
|
|
🤖 merged-by: apollo · lane: kanban-merge-pass · gate: BYPASS: FleetReview paused by Ace 2026-09-22 (state/fleetreview-pause marker present) · why: t_46a2f8a1: Flake: test_kanban_progress_stall "_wait_idle: pid never read idle to the real p; Argus off card review (Ace 13:08), CI green |
|
🤖 merged-by: apollo · lane: kanban-merge-pass · gate: BYPASS: FleetReview paused by Ace 2026-09-22 (state/fleetreview-pause marker present) · why: t_46a2f8a1: Flake: test_kanban_progress_stall "_wait_idle: pid never read idle to the real p; Argus off card review (Ace 13:08), CI green |
Card t_46a2f8a1. Fixes the
_wait_idle: pid never read idle to the real probeflake in tests/hermes_cli/test_kanban_progress_stall.py (PR #999 CI slice 1/16), and the production bug under it.Root cause.
_worker_cpu_activereadps -o pcpu. On Linux (procps), pcpu is lifetime CPU time divided by lifetime elapsed time, not a current rate. Measured on ACE-AI: a child that burned 2 s of CPU and then blocked read pcpu 66.4 / 26.4 / 16.5 / 12.0 / 9.4 at 3 / 7.5 / 12 / 16.5 / 21 s of pure idleness, while its CPU-time delta over each 0.5 s window was 0.000 s. On macOS the same child reads 0.0 by 7.5 s, because there pcpu is a decaying average. That is why the test passes 10/10 on the Mac Studio and flakes on loaded Linux runners, where a slow-starting child cannot fall below 0.1% within 30 s.Production impact. This veto is the only process-level input to
detect_progress_stalls. On any Linux dispatcher host, a stalled worker that had ever done real work read nonzero pcpu for hours and vetoed its own reclaim. So the stall detector could not reclaim on Linux.Fix. Two
psutil.Process(pid).cpu_times()samples_CPU_SAMPLE_SECONDS(0.5 s) apart. It vetoes only when user+system time goes up in that window. psutil is already a core dependency. An exited or zombie process reads idle. psutil missing, AccessDenied, or any other probe error returns True, so the probe still never authorizes a kill. The 0.5 s sample only runs for runs already paststall_seconds.Tests.
test_past_cpu_burn_does_not_veto_a_worker_idle_now. A real child burns about 1 s of CPU, signals, then blocks, and the probe must read idle. This is the class regression test.test_exited_process_reads_idle.subprocess.run. It covers AccessDenied, OSError, RuntimeError and psutil missing._wait_idlenow needs 3 consecutive delta samples instead of 6 pcpu samples.Linux verification on ACE-AI (load about 45-65 from its CI runners) will be posted as a comment.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.