You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The WPF Viewer computes the fleet deadlock total a third time, with the same structural-zero defect — and sharing the coverage type crosses an assembly boundary #3029
The WPF Viewer computes the fleet deadlock total a third time, independently of the MCP tool and the web dashboard, and it carries the same structural-zero defect #3017 was filed about. Fixing it is not a rendering change — it crosses an assembly boundary — which is why it is filed here rather than folded into #3027.
The finding
Darling/PerformanceMonitor.Darling.Viewer/ViewerDataService.Fleet.cs's FleetTotalsSql runs its own:
SELECTCOUNT(*) FROM v_deadlocks WHERE deadlock_time >= $1AND deadlock_time <= $2
That reaches the WPF Overview through FleetRollup.Build → MainWindow.xaml:876, as a bare binding:
On a PostgreSQL fleet it is structurally zero forever, exactly as get_fleet_overview was — v_deadlocks is written only by the SQL Server extended-event collector, and no v_pg_deadlocks exists. Same defect, same argument, different assembly.
And the same ambiguity: zero is also what a genuinely quiet SQL Server fleet reports, so the reading that needs no action and the reading that means "this total does not cover your fleet" are indistinguishable.
Why this is not the client-rendering change #3027 already shipped
Checked rather than assumed:
PerformanceMonitor.Darling.Viewer does not reference PerformanceMonitor.Darling.Service. Its ProjectReferences are Common, Ui, PlanAnalysis, Alerting, Analysis, Notifications, Darling.Analysis, Collectors, Darling.Storage. So FleetDeadlockSource, FleetDeadlockCoverage and ClassifyDeadlockSource are unreachable from it.
Sharing them means moving a public enum, a public DTO and a classify method out of the Service into Common. That is arguably the right home — "banding lives once" is this codebase's own line — but it is a public type crossing assemblies, and the Service's JSON-shape pins have to be re-verified afterward.
The Viewer's Overview read selects no engine_kind at all.engine_kind appears only in ViewerDataService.MonitoredServers.cs and ViewerDataService.cs, never on the Overview path, and ServerSummaryItem carries no PostgreSQL flag. Both the read and the DTO have to grow one.
The Viewer's summary path keeps only a FAILING count, not the per-collector band, so the deadlocks collector's band has to be retained through it the way the service reader now does.
Plus MainWindow.xaml and ViewerFleetRollupTests.cs (626 lines).
Roughly five more files including the cross-assembly move.
Why it was split rather than folded
#3027 was already at review shape on a ~1000-line dual-gate diff, and its routing instruction was explicitly "no server-side change" — which this cannot honour. The cross-assembly public-type relocation is a different review class and deserves its own reviewers' full attention rather than a rider slot on a diff that size. Same call as #3017 item 3, which also went to its own lane.
The costing above is carried over verbatim so whoever picks this up starts from the ProjectReference facts rather than rediscovering them.
What a fix has to decide
Where the shared types live. Common is the obvious home if "banding lives once" holds, but the move has to leave the Service's existing JSON-shape pins green.
Whether the Viewer needs the full coverage object or a narrower signal. The web tile takes servers_read/servers_total and renders a sub-line; the WPF Overview is a single bound string today and may want something different.
What the tile shows when coverage is complete, which Fixes #3017 (items 1 and 2) #3027 had to decide for the web surface — a permanent "12 of 12" trains people to ignore it, while showing something only on incomplete coverage means absence carries meaning.
Priority
Same defect family as #3017, so it inherits that priority rather than urgency. Nothing is newly broken; the number has read this way for as long as the Viewer has had the tile.
Closed by #3042, merged to dev at 3d9b049a53da3f78bfe7e36a45a752dcdefb20cf. Closing by hand because a closing keyword does not fire against dev.
The WPF Overview's Deadlocks: N now carries its coverage, so a structural zero and a genuinely quiet fleet stop reading the same. The shared types moved to PerformanceMonitor.Common and the service's wire shape did not change — the emitted JSON is byte-identical across the move, md5 c6cfb86cfd50ca3e418016d592fdaf7a, measured on both branches and staleness-controlled by mutating a moved constant and watching the hash move and return.
Two corrections to this issue's costing, both in the cheaper direction. The Overview read does not need to grow an engine_kind select: DarlingServer already carries IsPostgres through both registry reads and LoadOverviewAsync already stamps ServerName from it, so no summary query changed. The collector band is likewise free — it comes out of the collection-health rows already being enumerated to count HEALTHY and FAILING.
A fifth uncovered cause exists that the service has no equivalent of, and it deliberately keeps its own words. The viewer's summaries silently drops a server whose per-server read failed this cycle (#2753). That server is uncovered for the same reason a null band is, but folding it into the silent-collector cause would send the reader to a collector when the thing that failed was the viewer's own read. So the denominator is the registered fleet, the four causes deliberately do not sum to it, and the shortfall stays UnknownCount and is named in the tooltip. No always-zero fifth field was added to the wire.
Not verified, stated rather than implied: nothing was rendered. Wrap behaviour, the two brushes against the dark theme and tooltip length on screen are all unobserved — only that the bindings compiled into BAML. No PostgreSQL-only fleet was loaded in the viewer, so the measured case is asserted over constructed cards.
One side finding, chipped rather than filed: PgDeadlocksGrid sits under the "Vacuum" tab while its own comment says "Activity".
The WPF Viewer computes the fleet deadlock total a third time, independently of the MCP tool and the web dashboard, and it carries the same structural-zero defect #3017 was filed about. Fixing it is not a rendering change — it crosses an assembly boundary — which is why it is filed here rather than folded into #3027.
The finding
Darling/PerformanceMonitor.Darling.Viewer/ViewerDataService.Fleet.cs'sFleetTotalsSqlruns its own:That reaches the WPF Overview through
FleetRollup.Build→MainWindow.xaml:876, as a bare binding:Text="{Binding TotalDeadlocks, StringFormat='Deadlocks: {0}'}"On a PostgreSQL fleet it is structurally zero forever, exactly as
get_fleet_overviewwas —v_deadlocksis written only by the SQL Server extended-event collector, and nov_pg_deadlocksexists. Same defect, same argument, different assembly.And the same ambiguity: zero is also what a genuinely quiet SQL Server fleet reports, so the reading that needs no action and the reading that means "this total does not cover your fleet" are indistinguishable.
Why this is not the client-rendering change #3027 already shipped
Checked rather than assumed:
PerformanceMonitor.Darling.Viewerdoes not referencePerformanceMonitor.Darling.Service. Its ProjectReferences are Common, Ui, PlanAnalysis, Alerting, Analysis, Notifications, Darling.Analysis, Collectors, Darling.Storage. SoFleetDeadlockSource,FleetDeadlockCoverageandClassifyDeadlockSourceare unreachable from it.Sharing them means moving a public enum, a public DTO and a classify method out of the Service into Common. That is arguably the right home — "banding lives once" is this codebase's own line — but it is a public type crossing assemblies, and the Service's JSON-shape pins have to be re-verified afterward.
The Viewer's Overview read selects no
engine_kindat all.engine_kindappears only inViewerDataService.MonitoredServers.csandViewerDataService.cs, never on the Overview path, andServerSummaryItemcarries no PostgreSQL flag. Both the read and the DTO have to grow one.The Viewer's summary path keeps only a FAILING count, not the per-collector band, so the
deadlockscollector's band has to be retained through it the way the service reader now does.Plus
MainWindow.xamlandViewerFleetRollupTests.cs(626 lines).Roughly five more files including the cross-assembly move.
Why it was split rather than folded
#3027 was already at review shape on a ~1000-line dual-gate diff, and its routing instruction was explicitly "no server-side change" — which this cannot honour. The cross-assembly public-type relocation is a different review class and deserves its own reviewers' full attention rather than a rider slot on a diff that size. Same call as #3017 item 3, which also went to its own lane.
The costing above is carried over verbatim so whoever picks this up starts from the ProjectReference facts rather than rediscovering them.
What a fix has to decide
servers_read/servers_totaland renders a sub-line; the WPF Overview is a single bound string today and may want something different.Priority
Same defect family as #3017, so it inherits that priority rather than urgency. Nothing is newly broken; the number has read this way for as long as the Viewer has had the tile.