Skip to content

Thread cancellation through 7 Blocking web reads (#4203) - #4360

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

erikdarlingdata merged 2 commits into
devfrom
fix/4203-web-read-cancellation-4

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Refs #4203.

Why

Web /api/read/* handlers give each read HttpContext.RequestAborted, but the seven blocking / deadlock tools in DarlingMcpBlockingTools.cs were on DarlingWebEndpoints.CancellationAllowlist: an abandoned request kept running its store query to completion instead of stopping. This slice follows #4357's pattern (the Performance-Trends tools) over the Blocking family.

What changes

Darling/PerformanceMonitor.Darling.Service/Mcp/DarlingMcpBlockingTools.cs:

  • get_blocked_process_xml, get_blocking (both overloads), get_blocking_trend, get_deadlock_detail, get_deadlock_trend, get_deadlocks, get_lock_wait_trend (both overloads) each take a trailing CancellationToken cancellationToken = default and pass it to every store call in the body (resolver, reader, capability/precondition status, capture-count and existence probes).
  • Each tool's catch (Exception ex) narrows to catch (Exception ex) when (ex is not OperationCanceledException), so a cancellation propagates instead of being folded into an error payload.

Darling/PerformanceMonitor.Darling.Service/Mcp/DarlingServerResolver.cs:

  • ResolveWithFingerprintNameAsync gained a CancellationToken cancellationToken = default parameter (the get_blocking/get_deadlocks/get_deadlock_detail dedup_key path needs it) and threads it to its own registry read.

Darling/PerformanceMonitor.Darling.Service/DarlingWebEndpoints.cs:

  • The seven tool names are removed from CancellationAllowlist.
  • Their dispatch-table entries now pass c.RequestAborted.

Test plan

  • dotnet build Darling/Darling.Tests/Darling.Tests.csproj -p:EnableWindowsTargeting=true: 0 warnings, 0 errors.
  • PgTargetMcpSurfaceTests, McpServiceParameterDiSeatCensusTests, EngineCapabilityReadWiringTests, RuntimePreconditionReadWiringTests, WebReadCancellationPinTests (Windows-only; checked by inspection, no hardcoded allowlist count found, WebReadCancellationPinTests computes the shrink-only invariant dynamically against the dispatch table).
  • Full Windows test suite (net10.0-windows; cannot run on macOS, CI decides).

CHANGELOG entry

SECTION: Fixed
ENTRY:

For the coordinator

CancellationAllowlist shrinks by 7 in this slice. This will conflict textually with #4357 (also editing DarlingWebEndpoints.cs's allowlist and dispatch table) — the tender resolving that conflict should keep both slices' removals and dispatch-table changes.

pm-pr lane report (dev merge + verification)

Merge: git merge origin/dev (dev at 9ba47523) onto dfc2407a was a clean auto-merge (no manual conflict resolution needed) — the merge tool resolved DarlingWebEndpoints.cs on its own, keeping both siblings' CancellationAllowlist removals and dispatch-table c.RequestAborted wiring. New head: 87aa17694a654d2ad1c9d81d8ebc3afe6ce2b4da. Pushed with a plain git push (no force); PR head confirmed as a merge parent before push.

Allowlist diff (101 → 94): extracted the quoted-name set from CancellationAllowlist at origin/dev (101 entries) and at the merged HEAD (94 entries). Diff shows exactly the 7 tools removed (get_blocked_process_xml, get_blocking, get_blocking_trend, get_deadlock_detail, get_deadlock_trend, get_deadlocks, get_lock_wait_trend) and nothing added.

Build: dotnet build Darling/Darling.Tests/Darling.Tests.csproj -c Release → Build succeeded, 0 Warning(s), 0 Error(s).

Checks:

  1. Allowlist shrink — PASS (101→94, exact 7 removed, nothing added; see diff above).
  2. CancellationToken threading — PASS. All 7 [McpServerTool] methods in DarlingMcpBlockingTools.cs take CancellationToken cancellationToken = default and pass it to ResolveWithFingerprintNameAsync and their store/reader calls. No CancellationToken.None found in the file. ResolveWithFingerprintNameAsync's only other reference outside these 7 tools is the test census regex in McpPayloadContractCensusTests.cs (no other production caller exists) — build's 0 errors confirms nothing else needed updating.
  3. Catch-block narrowing — PASS. All 7 methods use catch (Exception ex) when (ex is not OperationCanceledException).
  4. Census/pin tests — PASS by inspection (Windows-only net10.0-windows tests can't execute on this macOS worktree; dotnet run for the test host fails with "No frameworks were found" for Microsoft.WindowsDesktop.App, a known repo constraint). PgTargetMcpSurfaceTests reflects on [McpServerTool] attribute names only, unaffected by this signature change. McpServiceParameterDiSeatCensusTests explicitly excludes CancellationToken parameters from its DI census. EngineCapabilityReadWiringTests/RuntimePreconditionReadWiringTests use a text regex over NotCollectedStatusAsync(...) calls that already tolerates an optional trailing cancellationToken/ct/CancellationToken.None argument. WebReadCancellationPinTests computes its assertions dynamically off DarlingWebEndpoints.BuildReadDispatch() and CancellationAllowlist (no hardcoded count), so the shrink-only invariant holds structurally.
  5. CHANGELOG entry — one line, true to diff. Fixed the REF link, which pointed to pull/4203 (the issue) instead of pull/4360 (this PR); now corrected. Body says Refs #4203.

get_blocked_process_xml, get_blocking, get_blocking_trend, get_deadlock_detail,
get_deadlock_trend, get_deadlocks and get_lock_wait_trend now take a
CancellationToken and pass it down to every store call, so an abandoned
web request stops its query instead of running to completion. Removes
the seven from CancellationAllowlist.
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 26, 2026 01:11
@erikdarlingdata
erikdarlingdata merged commit e12cdc9 into dev Sep 26, 2026
16 of 18 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/4203-web-read-cancellation-4 branch September 26, 2026 01:11
erikdarlingdata added a commit that referenced this pull request Sep 26, 2026
…33Z UTC (#4440)

Moves the CHANGELOG entries carried in merged pull-request descriptions into [Unreleased]. The cut is PRs merged at or before 2026-09-26T17:37:33Z; the next splice starts after it.

- 128 PRs are spliced: Fixed 87, Changed 20, Added 17 and Security 5. Each entry sits at the top of its section, newest PR first, and its link definition joins the trailing block.
- 22 PRs have no user-visible entry (None, test-only, or deferred to a parent).
- Three entries had no section in their description, and each was assigned from its diff: #4363, #4383 and #4380 go under Security.
- Link fixes: the #4198 references point at the issue, and #4360's [#4203] label points at issue 4203.
- #4208's entry is taken from its diff.
- Two security entries are worded to the current state: #4351's rotation note, and #4363's journal-read line.
- Only CHANGELOG.md changes.
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