CPU and I/O latency reach robust-baseline parity in Darling (#1743 follow-up) - #1995
CPU and I/O latency reach robust-baseline parity in Darling (#1743 follow-up)#1995erikdarlingdata wants to merge 1 commit into
Conversation
Both arms move off their sum/sumsq rollups (mean/stddev reconstructible, median structurally impossible) onto the raw hypertables at Lite's exact grain, through the shared robust scaffold. Measured before built, twice: a 4-day raw window would never satisfy the distinct-day trust floors (0 of 5,044 full buckets trustworthy on the production store) - a regression to the fallback bar - but the 4-day premise itself does not apply: cpu_utilization and file_io_stats carry their own 30-DAY service-side retention (CollectorScheduleDefaults 1-min/30d; verified on the production store - no TimescaleDB retention policy, full store life present, compressed after a day). Validated on the fleet's busiest tenant: 227 ms for the full window, tier structure exact (168+24+1), 42 full buckets already trustworthy at 16 days and every hour-only sentinel trustworthy - the tier ladder rides store age correctly. Supply pins move with the reasons: nine aggregate-fed families keep their pin; the two raw reads pin to their exact tables; and a NEW pin (RawBaselineFamilies_RetentionCoversTheWindow) turns the load-bearing invariant into a red build - drop either collector's retention below the baseline window and the build fails naming #1757. Retired rollup aggregates stay registered for upgrade compatibility; removal is separate cleanup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ReviewWhat this does: brings Darling's CPU and I/O latency baselines to parity with Lite by reading the raw One correctness concern worth a look (posted inline): switching CPU/IO from the aggregate views to raw-table reads removes a structural retention guarantee those two families used to have. I left the details on No Lite/Darling parity issues found — this PR is closing a parity gap, and the new SQL text matches Lite's shape wherever the Postgres/DuckDB dialects allow. No security concerns (no new external input paths, no dynamic SQL — the retention lookup is a compiled dictionary key). No missing-index recommendations included, per instructions. |
| this computes are the SAME per-sample statistics the rollup reconstruction produced. | ||
| The now-unused cpu_utilization_baseline aggregate remains registered for upgrade | ||
| compatibility; retiring it is separate cleanup. */ | ||
| MetricNames.Cpu => @" |
There was a problem hiding this comment.
Retention guarantee weakened for CPU/IO, with no runtime guard — only a build-time default pin.
Before this PR, CPU and I/O baselines were served by cpu_utilization_baseline/file_io_baseline, which are entries in TimescaleSupport.BaselineAggregates. That array feeds RetentionPolicies (TimescaleSupport.cs ~1921-1926), which gives every baseline aggregate a fixed, product-controlled BaselineRetentionInterval (35d) — structurally independent of anything a user configures, "by construction" per the leaf-rule comment there.
After this PR, CPU/IO read the raw cpu_utilization_stats/file_io_stats hypertables directly. Per the PR description, these tables have no TimescaleDB retention policy — they purge via DarlingRetention.cs's drop_chunks, keyed to the user-editable CollectorScheduleDefaults/schedule-editor retention (CollectorScheduleEditorWindow.xaml.cs enforces only RetentionDays >= 1, not >= the 30-day baseline window).
So a Darling operator who shortens cpu_utilization or file_io_stats retention via the schedule editor (a legitimate, supported action — same UI Lite's WarnIfRetentionUndercutsBaselineWindow exists specifically to guard against) will silently regress these two families back into the #1757 short-supply shape. Nothing in this PR catches that at runtime:
RawBaselineFamilies_RetentionCoversTheWindow(Darling.Tests) only pins the code default (CollectorScheduleDefaults.All["cpu_utilization"].RetentionDays >= 30) — it can't see a live store's configured retention.PgBaselineProviderhas no equivalent of LiteBaselineProvider's_retentionDaysForCollectorseam /WarnIfRetentionUndercutsBaselineWindowwarning at all.
Worth either wiring a runtime warning analogous to Lite's for these two collectors, or enforcing a >=30-day floor specifically for cpu_utilization/file_io_stats in the schedule editor (the way the baseline aggregates' retention is structurally guaranteed regardless of user config). As shipped, this PR trades a structural guarantee for a build-time-only one.
Closes the coverage asymmetry #1994 shipped with: Darling's CPU and I/O latency baselines read sum/sumsq rollups that cannot produce a median, so those two families degraded to the classical gate while Lite had robust statistics on all nine non-event metrics.
Measured before built — twice
cpu_utilizationandfile_io_statsare not on the 4-day raw tier at all — they carry their own 30-day service-side retention (CollectorScheduleDefaults: 1-minute cadence, 30-day retention; verified on the production store — no TimescaleDB retention policy, the store's full life present, compressed after a day).What
RawBaselineFamilies_RetentionCoversTheWindow) makes the load-bearing invariant a red build — if either collector's retention ever drops below the 30-day baseline window, the build fails naming PgBaselineProvider times out client-side scanning raw history, and tiered retention will mask it rather than fix it #1757 instead of quietly regressing the baselines.cpu_utilization_baseline/file_io_baselineaggregates stay registered (upgrade compatibility); removing them is separate cleanup.Sequencing
Merges after tonight's nightly was cut, so #1994 gets its clean solo dogfood window on the monitor box; this rides the next nightly through the same soak.
🤖 Generated with Claude Code