Skip to content

Fleet overview: an Azure master's deadlock last-seen comes from its own databases, and the Viewer card shows no sibling's Last - #4932

Merged
erikdarlingdata merged 8 commits into
devfrom
fix/fleet-master-last-seen
Oct 2, 2026
Merged

erikdarlingdata merged 8 commits into
devfrom
fix/fleet-master-last-seen

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Follow-up to #4925.

What was wrong

#4925 scoped an Azure SQL Database master's blocking and deadlock counts to its own databases, but left the "last seen" times alone. A master whose own databases had no deadlocks still showed "0 deadlocks, last seen minutes ago" on the fleet card (/api/fleet, MCP get_fleet_overview), because the time came from a separately monitored database's deadlock. The Darling Viewer's Overview card did the same: under 0 blocking and 0 deadlocks it read "Last: 2m ago" from a sibling's event.

The fix

  • The fleet card: PgFactCollector.CountAndNewestDeadlocksSkippingSeparateAsync returns the scoped deadlock count AND the newest deadlock that count includes, in ONE pass, with the count's own rule: the outside rows give COUNT(*) and MAX(deadlock_time) in SQL, and each graph that counts (not every process in a separately monitored database) adds to the count and to the newest. Its statements have the same predicates, window, collection floor and parameters as the count-only statements, so the count is unchanged. CountDeadlocksSkippingSeparateAsync is unchanged (the anomaly detector uses it).
  • DarlingFleetReader.ReadAzureMasterScopedCountsAsync makes that one call, and the fleet card's deadlock_last_seen takes the scoped time. The counts and the time come from the same read, so a failure can't separate them: a throw keeps that master's whole unscoped row, as before. MCP get_server_summary (which has no last-seen field) now makes one graph pass instead of two.
  • The Darling Viewer: a master with separately monitored databases shows NO "Last: N ago" on its Overview card, for blocking (the extended-events and DMV sides) or deadlocks. That time looks back over all stored history, and a master's own-database newest would need an all-history read or a cache on every refresh. Its counts stay scoped, and its Blocking and Deadlocks lists keep every row, with the note saying where those databases' events are counted. Every other server, a master with no separately monitored databases, and a master whose list lookup fails keep today's "Last".
  • The fleet card has no blocking last-seen field. MCP get_server_summary has no last-seen field. Lite's card shows no "Last", so Lite is unchanged. The web fleet page shows a last-seen only when the count is above 0.

Pins

  • FleetOverviewAzureMasterScopeLiveTests.MasterCard_DeadlockLastSeen_IsTheNewestOfItsOwnDatabases: with a sibling's deadlock newer than master's own, master's card shows its own newest (and null when it has none).
  • TheCombinedDeadlockPass_AgreesWithTheCountOnlyPass_AndFindsTheNewestCounted: an outside row, an all-in graph, a mixed graph, a graph with no database and a row with no event time; the count equals the count-only method's, the newest is the newest counted row, and a newer all-in graph is skipped.
  • TheScopedCounts_MakeOneDeadlockPass: the scoped reads call the combined method once.
  • ViewerFleetAzureMasterScopeLiveTests.TheMastersCard_ShowsNoLastForBlockingOrDeadlocks: a scoped master under 0/0 with newer sibling events has no "Last" in either detail, also when a scoped read fails; after a failed list lookup it keeps the unscoped "Last"; a plain server and a master with no siblings keep theirs; the counts are unchanged.
  • The two throw tests also assert that a failure keeps the unscoped last-seen.
  • The fleet pin failed at the tests commit (the card carried the sibling's newer time). On dev the Viewer's master shows a "Last" about 5 minutes ago from the sibling's rows, so the Viewer pin's no-"Last" assertions cannot pass there.

Tests run

  • Lite.Tests and Darling.Tests build with 0 warnings and 0 errors.
  • Darling.Tests in-process, on a live PostgreSQL store, all passing: ViewerFleetAzureMasterScopeLiveTests (12), FleetOverviewAzureMasterScopeLiveTests (12), AzureMasterAnalysisScopeLiveTests (21), DarlingMcpHealthToolsLivePostgresTests (2), DarlingFleetReaderSqlTests (33), DarlingFleetDeadlockCoverageTests (23), ViewerOverviewSqlTests (11), ViewerFleetDeadlockCoverageTests (29), McpPayloadContractCensusTests (68), ViewerDailySummaryAzureMasterScopeLiveTests (3), StorageCommandTimeoutTests, McpReadCommandTimeoutTests, and the T-SQL, doc-comment, repo-file and deadline-scanner guards.

CHANGELOG

None: part of the fleet overview's Azure master entry (#4925).

@erikdarlingdata erikdarlingdata changed the title Fleet overview: an Azure master's last-seen times come from its own databases, like its counts Fleet overview: an Azure master's deadlock last-seen comes from its own databases, and the Viewer card shows no sibling's Last Oct 2, 2026
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review October 2, 2026 02:41
@erikdarlingdata
erikdarlingdata merged commit d60f9c6 into dev Oct 2, 2026
17 of 18 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/fleet-master-last-seen branch October 2, 2026 02:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant