Repository navigation
Stuck-compression detector: -infinity while Running is the mid-run marker, not death - #2131
Conversation
…rker, not death Measured live on TimescaleDB 2.x (pg17): from scheduler pickup to run completion, job_stats.next_start reads -infinity with job_status = 'Running' — the engine computes the real next start only when the run finishes. The detector's first arm treated -infinity unconditionally as 'the scheduler will never run it again', so: - the self-alert check flagged any healthy compression run it happened to sample, alerted it, and 'self-healed' it with a pointless re-arm — the field's transient stuck→self-healed alert pairs were this false positive, and - the stuck-detector live test flaked in CI twice today on unrelated PRs: it re-arms with next_start => now() and then read a SINGLE snapshot while the run it had just triggered was still executing. A Running job's -infinity now defers to the elapsed-bound arm (which is what distinguishes a hung run from a healthy one); -infinity on a non-running job still alerts exactly as before. New pure pins cover the mid-run marker and the hung-run-with-marker case; the live test's leg (3) settles via the existing detector-polling helper instead of racing its own triggered run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ReviewWent through the diff ( Correctness —
Parity — no Lite counterpart exists for this detector ( Security/perf — no new I/O, no string-built SQL (the One very minor nit, not blocking: the new CHANGELOG entry is the only "Fixed" bullet in the Unreleased section without a No correctness, parity, or security issues found. |
Root-causes today's repeat CI flake (two hits in ~90 minutes on unrelated PRs #2124/#2128, both at
CompressionJobSelfHeal_DetectionQueryValid_AndRearmSucceedsleg 3) — and the field's transient stuck→self-healed alert noise turns out to be the same product bug.The engine fact, measured live
On TimescaleDB 2.x (pg17, tight-polled through a triggered run):
From scheduler pickup to run completion,
job_stats.next_startreads-infinitywithjob_status = 'Running'— the engine computes the real next start only at completion. So-infinityalone does not mean "the scheduler will never run it again".What that meant
IsCompressionJobStuck's first arm fired on-infinityunconditionally, so the self-alert check flagged any healthy compression run it happened to sample, alerted it as stuck, and "self-healed" it with a pointless re-arm. The stuck→self-healed alert pairs the box protocol has been excusing as "detection working" were largely this false positive.next_start => now()(making the job immediately due) and then asserted on a single snapshot — racing the very run the re-arm triggered. Different sibling-fixture jobs appear in each failure's collection because the fixture's policies run their first check immediately on creation.The fix
-infinitydefers to the elapsed-bound arm —StuckRunningBoundis what actually distinguishes a hung run from a healthy one.-infinityon a non-running job (the field's dead-scheduler case) still alerts exactly as before, and a hung run carrying the mid-run marker still trips the bound.WaitUntilDetectorReportsHealthyAsync(the same helper leg 1 already uses) instead of racing its own triggered run.🤖 Generated with Claude Code