Skip to content

Cancel background task runners on server disposal - #1715

Open
jstar0 wants to merge 2 commits into
modelcontextprotocol:mainfrom
jstar0:fix/server-lifetime-task-runners
Open

Cancel background task runners on server disposal#1715
jstar0 wants to merge 2 commits into
modelcontextprotocol:mainfrom
jstar0:fix/server-lifetime-task-runners

Conversation

@jstar0

@jstar0 jstar0 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Background Tasks runners used cancellation sources independent of the owning
server and discarded their Task handles. As a result, server disposal could
finish before a runner was cancelled, including when the runner registered
during disposal.

Changes

  • Add a general server-lifetime cancellation and IAsyncDisposable
    registration seam for extension infrastructure, with an unregistration
    handle so completed work is not retained.
  • Cancel the lifetime at the start of stateful server disposal, close
    registration after request handlers drain, and await the remaining runners.
  • Let each Tasks runner state own cancellation and completion awaiting, while
    long-lived MRTR handlers remain linked to the server lifetime and completed
    registrations are removed.
  • Keep stateless HTTP request servers non-owning so Tasks can continue across
    independent requests.
  • Add deterministic coverage for cancellation, awaiting, late registration,
    and the stateless ownership boundary.

The change does not alter protocol messages, task-store contracts, polling, or
explicit tasks/cancel behavior.

Verification

dotnet test tests/ModelContextProtocol.Tests/
dotnet test tests/ModelContextProtocol.Analyzers.Tests/
dotnet build
dotnet pack
dotnet docfx docs/docfx.json --warningsAsErrors true

The current lifetime-registration focus passed on net10.0, net9.0, and net8.0
(5 tests on each framework). The merged net10.0 lifecycle and Tasks
execution-mode focus passed 61 tests. The full Core suite passed with 2328 passed and 5
skipped; the analyzer suite passed with 57 passed. The Release solution build
completed with 0 warnings and 0 errors, package validation produced all
packages, and DocFX completed with 0 warnings and 0 errors.

Closes #1707

@jstar0
jstar0 force-pushed the fix/server-lifetime-task-runners branch from ff309e9 to 456f064 Compare July 25, 2026 16:50
Comment thread src/ModelContextProtocol.Core/Server/McpServerImpl.cs Outdated
@jeffhandley jeffhandley added this to the 2.x milestone Jul 27, 2026
@jstar0
jstar0 force-pushed the fix/server-lifetime-task-runners branch from 02fb82c to db7f5c3 Compare August 20, 2026 17:16
@jstar0

jstar0 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and refreshed the lifecycle tests for the current request-filter API.

Local verification after the rebase:

  • focused lifecycle tests: 5/5 passed on net10.0
  • full ModelContextProtocol.Tests suite: passed on net10.0
  • make build CONFIGURATION=Release: passed with 0 warnings and 0 errors

The new hosted run is in progress. The earlier Windows Release failure was in the unrelated OAuth metadata fallback test (duplicate fallback requests), not in the files changed here.

@jstar0

jstar0 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

The Windows Release job for head db7f5c3042103defe06c3707fe5e6898cee75952 completed with two failures outside the files changed in this PR:

  • RawHttpConformanceTests.July2026Post_MissingRequiredCapability_Returns400 (net8.0): expected BadRequest, actual OK.
  • OAuth.TokenCacheTests.GetTokenAsync_InvalidCachedTokenTriggersAuthDelegate: failed to find authorization-server metadata for https://localhost:7029/.

Windows Debug, Ubuntu Debug/Release, and macOS Debug/Release passed. Could you please rerun the Windows Release job or confirm whether these failures reproduce on the base branch? The lifetime/task-runner changes in this PR do not touch the ASP.NET conformance or OAuth test paths.

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.

Deterministically cancel background task-store runners on server disposal via a server-lifetime CTS

3 participants