Repository navigation
Thread cancellation through 10 Alerts/MemoryGrants/Health web reads (#4203) - #4386
Merged
Merged
Conversation
…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
marked this pull request as ready for review
September 26, 2026 06:17
This was referenced Sep 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #4203.
Why
Per #4203, web reads should honour request cancellation so an abandoned
/api/readrequest 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 inDarlingMcpAlertTools.cs,DarlingMcpMemoryGrantTools.csandDarlingMcpHealthTools.cs.What changes
Ten tools now take a trailing
CancellationToken cancellationToken = default, pass it to every store call in their bodies, narrow their catch towhen (ex is not OperationCanceledException), and are removed fromCancellationAllowlist; their dispatch entries now passcancellationToken: c.RequestAborted:get_alert_historyget_alert_settingsget_mute_rulesget_notification_routesget_resource_semaphoreget_memory_grantsget_memory_pressure_eventsget_server_summaryget_daily_summaryget_daily_summary_rangeget_mute_rules's store call (PgMuteRuleStore.LoadAllAsync) required a shared-interface change:IMuteRuleStore.LoadAllAsyncgained aCancellationToken cancellationToken = defaultparameter. 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 deprecatedJsonMuteRuleStore(Dashboard, synchronous, param added for compile parity only). Test fakes (Darling.Tests/MuteRuleReloadRetentionTests.cs'sScriptedMuteRuleStore,Darling.Tests/DarlingMcpAlertToolsTests.cs'sFakeMuteRuleStore,Lite.Tests/RemainingEmptyReadsToolTests.cs'sInMemoryMuteRuleStore,Lite.Tests/MuteRuleServiceTests.cs'sFakeMuteRuleStore) all had the same parameter added to their overrides so every other caller ofLoadAllAsync()(the write-verb toolscreate_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_enabledanddelete_notification_route(write verbs) andcreate_mute_rule/delete_mute_rule/set_mute_rule_enabled/update_mute_rule(write verbs) were left untouched: none were inCancellationAllowlistto 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.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 threadingc.RequestAborted, so a cancelled request's underlying store call ran to completion — the pin'sEveryStoreReadingToolMethod_TakesACancellationToken_UnlessAllowlistedcheck 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).CHANGELOG entry
SECTION: Fixed
ENTRY:
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_summaryandget_daily_summary_rangepreviously ran their store query to completion even after an abandoned web request; they now take aCancellationTokenand pass it through every store call.REF:
[Thread cancellation through 10 Alerts/MemoryGrants/Health web reads (#4203) #4386]: Thread cancellation through 10 Alerts/MemoryGrants/Health web reads (#4203) #4386