Skip to content

Thread cancellation through 15 core web reads (#4203) - #4387

Merged
erikdarlingdata merged 5 commits into
devfrom
fix/4203-web-read-cancellation-8
Sep 26, 2026
Merged

erikdarlingdata merged 5 commits into
devfrom
fix/4203-web-read-cancellation-8

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

Refs #4203.

Why

DarlingWebEndpoints.CancellationAllowlist listed 15 tools in DarlingMcpDataTools.cs whose dispatch entries did not thread c.RequestAborted through, so an abandoned web-viewer request kept running its store query to completion instead of stopping.

What changes

Added a trailing CancellationToken cancellationToken = default parameter (no [Description]) to each tool method below, passed it to every store call in the body (resolver, reader calls, engine-capability/runtime-precondition probes, memoized reads), narrowed each catch (Exception ex) to when (ex is not OperationCanceledException), removed the tool from CancellationAllowlist, and updated its DarlingWebEndpoints dispatch entry to pass cancellationToken: c.RequestAborted:

  • get_cpu_utilization
  • get_wait_stats
  • get_wait_types
  • get_wait_trend
  • get_memory_stats
  • get_memory_clerks
  • get_file_io_stats
  • get_tempdb_trend
  • get_perfmon_stats
  • get_query_store_top
  • list_servers
  • get_collection_health
  • get_collection_log (both the per-server and the fleet-wide branch, GetCollectionLogFleetAsync)
  • get_current_waits_trend
  • get_blocking_stats

All 15 were allowlisted in DarlingWebEndpoints.cs and defined in DarlingMcpDataTools.cs; get_top_queries_by_cpu, get_top_procedures_by_cpu, and get_server_properties are also defined there but were NOT in the allowlist, so they are untouched by this slice.

Every reader/helper call site below the tools (DarlingDataReader.*, DarlingServerResolver.ResolveOrErrorAsync, DarlingEngineCapability.NotCollectedStatusAsync, DarlingRuntimePrecondition.*, DarlingTrendReader.*, DarlingBlockingTrendReader.*) already accepted an optional CancellationToken cancellationToken = default, so no reader signatures changed — except one shared helper:

Shared-helper signature change: DarlingServerResolver.ResolveOrErrorWithFleetSentinelAsync gained a trailing CancellationToken cancellationToken = default (get_collection_log is the only caller on this SKU, so no other caller needed updating).

Test plan

  • dotnet build Darling/Darling.Tests/Darling.Tests.csproj -p:EnableWindowsTargeting=true — 0 Warning(s)/0 Error(s) beyond the pre-existing warning count (1 warning, 0 errors).
  • dotnet build Lite.Tests/Lite.Tests.csproj -p:EnableWindowsTargeting=true — 0 Warning(s)/0 Error(s).
  • Windows-only test suites (Darling.Tests, Lite.Tests target net10.0-windows and cannot run on macOS): UNCHECKED, CI decides them. The RED case for the existing pin: Darling/Darling.Tests/WebReadCancellationPinTests.cs's EveryStoreReadingToolMethod_TakesACancellationToken_UnlessAllowlisted reflection ratchet previously passed only because these 15 tools were allowlisted (an exemption from the token requirement); CancellationAllowlist_HasNoStaleEntry also previously passed trivially since all 15 were still-valid allowlist entries. Removing them from the allowlist without adding the token parameter would have made EveryStoreReadingToolMethod_TakesACancellationToken_UnlessAllowlisted fail RED (a dispatch entry with no c.RequestAborted threaded through, matching the ratchet's own description); this PR adds the token to every one of the 15 dispatch entries, so on dev's pre-fix code (allowlist entry present, no token) the ratchet was silently non-failing by construction — the RED state proven here is: reverting the allowlist removal alone (leaving the token additions) would trip CancellationAllowlist_HasNoStaleEntry (a stale allowlist entry for a tool that now takes a token), and reverting the token additions alone (leaving the allowlist removal) trips EveryStoreReadingToolMethod_TakesACancellationToken_UnlessAllowlisted.
  • Did not run PgTargetMcpSurfaceTests, McpServiceParameterDiSeatCensusTests, EngineCapabilityMissTests, RuntimePreconditionMissTests locally (Windows-only); grepped and none of the 15 touched tools' catch-clause narrowing or parameter additions should change their existing assertions, since no response shape or parameter count/order changed other than the appended token.

CHANGELOG entry

SECTION: Fixed
ENTRY:

get_cpu_utilization, get_wait_stats, get_wait_types, get_wait_trend, get_memory_stats,
get_memory_clerks, get_file_io_stats, get_tempdb_trend, get_perfmon_stats, get_query_store_top,
list_servers, get_collection_health, get_collection_log and get_current_waits_trend/get_blocking_stats
now take a CancellationToken and pass it to every store call, so an abandoned web request stops
its query instead of running to completion. Removes them from CancellationAllowlist.
…ellation-8

# Conflicts:
#	Darling/PerformanceMonitor.Darling.Service/DarlingWebEndpoints.cs
@erikdarlingdata erikdarlingdata changed the title Thread cancellation through 14 core web reads (#4203) Thread cancellation through 15 core web reads (#4203) Sep 26, 2026
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 26, 2026 06:00
@erikdarlingdata
erikdarlingdata merged commit 78e0b12 into dev Sep 26, 2026
17 of 18 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/4203-web-read-cancellation-8 branch September 26, 2026 06:00
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