fix(server): expose session_idle_timeout via streamable_http_app() and pause reaping during active requests#2874
Open
Bartok9 wants to merge 1 commit into
Conversation
…d pause reaping during active requests Closes modelcontextprotocol#2455. session_idle_timeout existed only on StreamableHTTPSessionManager, so users of the high-level streamable_http_app() API had to drop down to manual session-manager wiring to configure idle reaping. Worse, the idle deadline was only pushed forward when a request *arrived*, so a request still being processed when the deadline passed could have its session reaped mid-flight. - Thread session_idle_timeout through Server.streamable_http_app() and MCPServer.streamable_http_app() into the session manager. - Track in-flight requests on the transport: mark_request_started() suspends idle reaping (deadline -> inf) while >=1 request is active; mark_request_finished() re-arms the deadline only when the last concurrent request completes, and is a no-op when no timeout is configured. - Wrap both stateful handle_request() call sites in start/finished so an active request is never counted as idle. - Move task_status.started() to after idle_scope is attached so the first request cannot race ahead of the scope it needs to suspend. Verification: 7 new tests (app forwarding + default None, transport suspend/resume across overlapping requests, no-timeout no-op, counter underflow guard); 249 streamable/idle/session tests pass; existing test_idle_session_is_reaped still green. ruff + pyright clean.
9 tasks
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.
Summary
session_idle_timeoutthrough the high-levelServer.streamable_http_app()/MCPServer.streamable_http_app()API so users no longer have to wire upStreamableHTTPSessionManagerby hand to configure idle reaping.Motivation
Closes #2455.
The
session_idle_timeoutfeature (from #1994 / #2022) had two linked problems:streamable_http_app()— the parameter existed onStreamableHTTPSessionManagerbut not on the canonical app-builder API, forcing users to drop down to manual session-manager wiring.Fix
session_idle_timeoutthrough bothstreamable_http_app()methods into the session manager.mark_request_started()/mark_request_finished()toStreamableHTTPServerTransport:startedincrements an active-request counter and pushes the idle deadline to+inf(suspends reaping).finisheddecrements the counter and re-arms the deadline only when the last concurrent request completes; it is a no-op when no timeout is configured, and the counter never underflows.handle_request()call sites intry/finallystart/finished pairs, so an active request is never counted as idle.task_status.started()to afteridle_scopeis attached, so the very first request can't race ahead of the scope it needs to suspend.Verification
uv run pytest tests/server/test_streamable_http_manager.py tests/server/test_streamable_http_security.py -q— 32 passeduv run pytest tests/ -q -k "streamable or idle or session_manager"— 249 passedtest_idle_session_is_reapedstill green (reaping of genuinely idle sessions unchanged).None; transport suspend/resume across overlapping requests; no-timeout no-op; counter-underflow guard.ruff format+ruff check+pyrightclean on all changed files.Notes
Rebuilds the intent of the stale, now-conflicting #2457 by @shaun0927 (same root cause and approach) cleanly against current
mainafter the server modules were refactored. Crediting the original approach on that PR.