Repository navigation
Bucket Lite's Performance Trends duration/execution charts (#4234) - #4338
Conversation
GetQueryDurationTrendAsync, GetProcedureDurationTrendAsync and GetExecutionCountTrendAsync used to return one row per collection over v_query_stats/v_procedure_stats -- a 7-day chart on a 1-minute cadence shipped thousands of rows. Buckets them server-side, sized by TrendBuckets.AutoMinutes against TrendBudget.Chart, the same shape the MCP twins in LocalDataService.TrendBuckets.cs already read. A bucket's rate is its rated collections' summed work over summed seconds (never the mean of per-collection rates); a bucket with no rated collection keeps its row with a NULL rate rather than being dropped, matching the existing per-collection #3541 A12 contract. Points stamp at bucket_start unless every bucket the call returns holds exactly one physical collection, in which case each stamps at that collection's own time. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
…rts (#4234) Pins the new server-side bucketing in GetQueryDurationTrendAsync, GetProcedureDurationTrendAsync and GetExecutionCountTrendAsync against embedded DuckDB: the SQL carries the bucket-width parameter, a dense 7-day window stays under TrendBudget.Chart's point budget, singleton 1-minute buckets reproduce the old per-collection read exactly (seeded off the minute grid, with a database filter), and a merged bucket sums rated work over rated seconds rather than averaging per-collection rates, keeping an all-unrated bucket's row with a NULL rate while a mixed bucket counts only its rated collection. Also makes DurationTrendChartSql and ExecutionCountTrendChartSql internal (they were private) so this suite can read the statement text directly. Proved these fail against the pre-bucketing code: the source-check test fails to compile (the new SQL builders do not exist yet), the three budget tests fail (1600 one-minute-apart collections return 1600 rows, over the 1500-point budget), and the three merged-bucket tests fail (5 rows instead of 3, one per collection rather than one per bucket). The three singleton-bucket tests pass unchanged against the old code too, which is correct: a 1-minute bucket holding exactly one collection must render identically to the unbucketed read. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
McpZeroIsAMeasurementTests.EveryDifferencedTrend_LeavesTheFirstPointUnrated_NeverZero still expected three per-collection LocalDataService.QueryStats.cs statements rating through `... END AS x_per_second`. #4338 merged the query and procedure duration trends into one bucketed statement (DurationTrendChartSql) that nulls an unrated bucket's work and seconds through no-ELSE CASEs (`END AS rated_x`) and divides the bucket's sums instead. Widen the `rated` regex to also match `rated_\w+`, drop the three delta-family counts to two (one merged statement replaces two), and add an assert that both statements null `rated_seconds` the same way. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
|
Lane report for the CI fix (test-only pin update). Commit: What changed in the pin (
Build: Test totals (
Revert-proofs (each rebuilt, run, and restored):
Each revert-proof's target file was restored to its pre-edit content immediately after observing the failure; DocCommentHygiene*: Not run: the full suite — CI runs it. No PostgreSQL rig was needed (unit tests only). Scope: test-only pin update per brief. Did not touch |
Part of #4234.
Why
Lite's Performance Trends chart (Queries tab, "Performance Trends" sub-tab) read three series at the
per-collection tier:
GetQueryDurationTrendAsync,GetProcedureDurationTrendAsyncandGetExecutionCountTrendAsync(Lite/Services/LocalDataService.QueryStats.cs), each one row percollection over
v_query_stats/v_procedure_stats. A 7-day chart on a 1-minute collection cadenceshipped thousands of rows per series to the desktop, the same defect #4234's earlier lanes already
fixed for Wait Stats, Perfmon, File I/O and memory-clerk charts. These are their only product callers
(
Lite/Controls/ServerTab.Refresh.cs~240-243 and ~318-321); the MCP tools already read their ownbucketed twins (
GetBucketedQueryDurationTrendAsync/ReadBucketedDurationTrendAsync,LocalDataService.TrendBuckets.cs), which this lane left untouched.What changes
Lite/Services/LocalDataService.QueryStats.cs:TrendBuckets.AutoMinutesagainstTrendBudget.Chart.AutoPoints, computed from the read's own window (the desktop's ownhoursBack/fromDate/toDate, soseriesCountis always 1). Public signatures are unchanged; eachmethod still takes exactly the parameters it did before.
the per-collection rates. A bucket with no rated collection (every collection in it a restart, or
the window's first pre-v61 collection) still gets a row with a NULL rate rather than being dropped
(no
HAVING) — the existing per-collection MCP payload-contract campaign: the agent-facing API tells the truth (~30 defects + an 11-rule contract) #3541 A12 contract ("an unrated collection is a pointwith no rate, not a missing point"), now applied per bucket. This is a deliberate difference from
the wait/perfmon trend reads, which drop an all-unrated bucket; these three reads already kept an
unrated row before this change, and bucketing does not alter that.
physical collection, in which case each stamps at that collection's own raw time — so a window
narrow enough to need no merging (in practice, most of what the chart shows today) renders exactly
as the unbucketed read did.
GetQueryDurationTrendAsyncandGetProcedureDurationTrendAsyncnow share one SQL builder,DurationTrendChartSql(relation, dbClause, widthParamIndex)(internal static, so a source test canread the text), and one row-reading body,
ReadDurationTrendChartAsync.relationis one of twoconstants (
v_query_stats,v_procedure_stats), never caller text.GetExecutionCountTrendAsynchasno shared builder (it is the only one of the three projecting a single rate column) and buckets in
place with its own
ExecutionCountTrendChartSql.BuildDbInClausedatabase list, so that list's own$4..numbering never shifts — the same choicethe wait/perfmon trend reads made.
QueryTrendPoint's fields stay filled exactly as before (Value,ExecutionCount,ExecutionsPerSecond); the MCP-only bucket fields (FirstCollectionTime,PeakElapsedMsPerSecond,UnratedInBucket) are not populated for these three chart reads, matching the brief.SUMover an INTEGER column returns HUGEINT; all bucket sums are read through the existingToDouble/ToInt64helpers, neverGetDouble/GetInt64.existing MCP payload-contract campaign: the agent-facing API tells the truth (~30 defects + an 11-rule contract) #3541 A12 / Brains-review campaign: deferred structural residue (from #3538 / #3539 / #3540 / #3541) #3653 A11 contract explanation it already carried.
Lite.Tests/PerformanceTrendDurationBucketingTests.cs(new): 10 tests against embedded DuckDB,covering all three reads:
DurationTrendChartSql/ExecutionCountTrendChartSqlcarry the bucket-widthparameter and keep the database filter's own numbering when it shifts the width's slot;
generate_seriesinsert) stays at or under
TrendBudget.Chart.AutoPoints(1,500) and meaningfully compresses (fewerpoints than collections), for each of the three reads;
grid (
:37seconds) with a database filter excluding a third collection — for each of the threereads;
the two per-collection rates; an unrated collection alone in a bucket gives a NULL point (kept, not
dropped); a bucket mixing an unrated collection with a rated one rates only the rated one — all
three in one seeded call per read, since none of them can be a singleton-only call.
DeltaFamilyUnknowableRowReadTests(existing, untouched) still exercises these three reads at 1-minutebuckets and passes unchanged, because its fixtures space collections 5 minutes apart — each its own
singleton bucket at the auto-chosen 1-minute width for its 3-hour window.
Test plan
Lite.Tests/Lite.Tests.csprojbuilds with 0 warnings.PerformanceTrendDurationBucketingTests— 10/10 passed.*DeltaFamilyUnknowable*,*QueryStats*,*TrendBucket*,*Duration*,DocCommentHygiene*) — 43/43 passed. (DocCommentHygieneonly exists inDarling.Tests, so itmatched zero tests here, as expected.)
origin/dev's version ofLocalDataService.QueryStats.cs. The source-check test fails to compile (the new SQL buildersdo not exist yet). With that one test temporarily removed so the rest could build, the three
budget tests failed (1,600 rows returned, over the 1,500-point budget) and the three
merged-bucket tests failed (5 rows instead of 3 — one per collection, not one per bucket). The
three singleton-bucket tests passed unchanged against the old code too, which is correct: a
1-minute bucket holding one collection must render identically to the unbucketed read. Restored
both files afterward.
origin/dev(no conflicts; the merged files don't touch anything this PR changed).Lite.Tests.exerun once after the merge: 5,425 total, 0 failed, 0 errors.rig was started or needed).
Scope note
Only these three reads were in this lane's brief. The MCP-facing bucketed twins in
LocalDataService.TrendBuckets.cs(GetBucketedQueryDurationTrendAsync,GetBucketedProcedureDurationTrendAsync,ReadBucketedDurationTrendAsync) were left exactly as theywere, per the brief. Other #4234 reads (Wait Stats/Perfmon pickers, the Darling viewer's own
query/procedure/execution-count charts, Overview lanes) are other lanes' work and were not touched.
CI fix
The first CI run failed one Darling source pin,
McpZeroIsAMeasurementTests.EveryDifferencedTrend_LeavesTheFirstPointUnrated_NeverZero, which reads this file and knew only the per-collection shape. The product code is unchanged. The pin now also accepts the bucketed shape's no-ELSE... END AS rated_xcolumns, counts two three-state interval statements instead of three (the query and procedure trends shareDurationTrendChartSql), and requires each of the two statements to null an unrated collection's seconds (be69745a, after a merge oforigin/dev). Report: PR comment 5837766944, with three revert-proofs.CHANGELOG entry
SECTION: Changed
ENTRY:
REF:
[Bucket Lite's Performance Trends duration/execution charts (#4234) #4338]: Bucket Lite's Performance Trends duration/execution charts (#4234) #4338
🤖 Generated with Claude Code
https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ