Skip to content

Thread cancellation through 10 Alerts/MemoryGrants/Health web reads (#4203) - #4386

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

erikdarlingdata merged 6 commits into
devfrom
fix/4203-web-read-cancellation-10

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

Refs #4203.

Why

Per #4203, web reads should honour request cancellation so an abandoned /api/read request stops its store query instead of running to completion. #4357 and #4359 did this for the Performance-Trends tools; this slice does the same for every allowlisted tool defined in DarlingMcpAlertTools.cs, DarlingMcpMemoryGrantTools.cs and DarlingMcpHealthTools.cs.

What changes

Ten tools now take a trailing CancellationToken cancellationToken = default, pass it to every store call in their bodies, narrow their catch to when (ex is not OperationCanceledException), and are removed from CancellationAllowlist; their dispatch entries now pass cancellationToken: c.RequestAborted:

  • get_alert_history
  • get_alert_settings
  • get_mute_rules
  • get_notification_routes
  • get_resource_semaphore
  • get_memory_grants
  • get_memory_pressure_events
  • get_server_summary
  • get_daily_summary
  • get_daily_summary_range

get_mute_rules's store call (PgMuteRuleStore.LoadAllAsync) required a shared-interface change: IMuteRuleStore.LoadAllAsync gained a CancellationToken cancellationToken = default parameter. Every implementation was updated to match: PgMuteRuleStore (now uses it on the connection open/reader), DuckDbMuteRuleStore (Lite, param added, not yet wired to the DuckDB calls — Lite has no cancellable read path here, kept as the smallest change), and the deprecated JsonMuteRuleStore (Dashboard, synchronous, param added for compile parity only). Test fakes (Darling.Tests/MuteRuleReloadRetentionTests.cs's ScriptedMuteRuleStore, Darling.Tests/DarlingMcpAlertToolsTests.cs's FakeMuteRuleStore, Lite.Tests/RemainingEmptyReadsToolTests.cs's InMemoryMuteRuleStore, Lite.Tests/MuteRuleServiceTests.cs's FakeMuteRuleStore) all had the same parameter added to their overrides so every other caller of LoadAllAsync() (the write-verb tools create_mute_rule, delete_mute_rule, set_mute_rule_enabled, update_mute_rule — none of them allowlisted, out of this slice's scope) still compiles unchanged against the new default parameter.

set_notification_route_enabled and delete_notification_route (write verbs) and create_mute_rule/delete_mute_rule/set_mute_rule_enabled/update_mute_rule (write verbs) were left untouched: none were in CancellationAllowlist to begin with, so they're out of this slice's scope per the brief.

Test plan

  • dotnet build Darling/Darling.Tests/Darling.Tests.csproj -p:EnableWindowsTargeting=true: 0 warnings, 0 errors.
  • dotnet build Lite.Tests/Lite.Tests.csproj -p:EnableWindowsTargeting=true: 0 warnings, 0 errors.
  • The existing WebReadCancellationPinTests (EveryStoreReadingToolMethod_TakesACancellationToken_UnlessAllowlisted, CancellationAllowlist_HasNoStaleEntry) is a reflection ratchet: removing these ten names from the allowlist makes it enforce them going forward. RED case before this change: any of the ten dispatch entries invoked its tool without threading c.RequestAborted, so a cancelled request's underlying store call ran to completion — the pin's EveryStoreReadingToolMethod_TakesACancellationToken_UnlessAllowlisted check would fail once the name left the allowlist while the method still lacked the parameter (the actual RED state on the pre-fix code, since the allowlist entry was masking the check).
  • Darling.Tests and Lite.Tests target net10.0-windows: they build here but cannot run on macOS — listed unchecked; CI decides them.

CHANGELOG entry

SECTION: Fixed
ENTRY:

…4203)

get_alert_history, get_alert_settings, get_mute_rules, get_notification_routes,
get_resource_semaphore, get_memory_grants, get_memory_pressure_events,
get_server_summary, get_daily_summary and get_daily_summary_range now take a
CancellationToken and pass it to every store call in their bodies, so an
abandoned web request stops its query instead of running to completion.
Removes all ten from CancellationAllowlist.

IMuteRuleStore.LoadAllAsync gained a CancellationToken parameter (default);
every implementation (Pg, DuckDb, Json) and test fake updated to match.
# Conflicts:
#	Darling/PerformanceMonitor.Darling.Service/DarlingWebEndpoints.cs
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 26, 2026 06:17
@erikdarlingdata
erikdarlingdata merged commit 29288f2 into dev Sep 26, 2026
17 of 18 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/4203-web-read-cancellation-10 branch September 26, 2026 06:17
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