Title: Evict streamable HTTP sessions after failed keep-alive pings by lxq19991111 · Pull Request #1028 · modelcontextprotocol/java-sdk · GitHub
Open Graph Title: Evict streamable HTTP sessions after failed keep-alive pings by lxq19991111 · Pull Request #1028 · modelcontextprotocol/java-sdk
X Title: Evict streamable HTTP sessions after failed keep-alive pings by lxq19991111 · Pull Request #1028 · modelcontextprotocol/java-sdk
Description: Summary
Fixes #1022.
Evict dead Streamable HTTP sessions after repeated keep-alive ping failures.
When keep-alive-interval is enabled, KeepAliveScheduler currently detects dead sessions by logging failed pings, but the failed sessions remain in the Streamable HTTP provider's session registry. Over time, the scheduler keeps pinging the same unreachable sessions every interval, causing repeated WARN logs and CPU usage that grows with the number of accumulated dead sessions.
This PR adds keep-alive success/failure hooks and lets the Streamable HTTP servlet provider evict the logical session after consecutive keep-alive failures.
Dependency / Review Order
Depends on #1027.
#1027 establishes the transport-level lifecycle behavior: servlet async lifecycle events and SSE write failures close only the current HTTP/SSE transport while keeping the logical MCP session registered.
This PR builds on that behavior by evicting the logical MCP session only after repeated keep-alive ping failures. After #1027 lands, this PR should be rebased on top of it so the keep-alive eviction behavior does not conflict with transport-level write-failure cleanup.
Related Issues and PRs
Fixes #1022.
Depends on #1027 for servlet async lifecycle cleanup and write-failure semantics.
Related to #952 and #972: this PR should not be interpreted as deleting the logical session on a single request-specific write failure. That behavior belongs to #1027 / #972.
Related to #920: transient write failures should not immediately orphan a session, so this PR uses a consecutive-failure threshold rather than evicting on the first failure.
Changes
Add success and failure callbacks to KeepAliveScheduler.
Keep the new scheduler callbacks backward compatible by defaulting them to no-op handlers.
Track consecutive keep-alive ping failures in HttpServletStreamableServerTransportProvider.
Reset the failure count after a successful keep-alive ping.
Evict and close a Streamable HTTP session after 3 consecutive keep-alive ping failures.
Clear failure counts on session deletion and provider shutdown.
Guard failure-count reset and eviction with session identity checks so stale keep-alive results cannot affect a replaced session.
Add focused tests for scheduler callbacks and Streamable HTTP keep-alive eviction behavior.
Rationale
The issue suggested doing the failure counter and session removal directly in KeepAliveScheduler. This PR intentionally keeps KeepAliveScheduler transport-agnostic.
KeepAliveScheduler only receives a Supplier
Open Graph Description: Summary Fixes #1022. Evict dead Streamable HTTP sessions after repeated keep-alive ping failures. When keep-alive-interval is enabled, KeepAliveScheduler currently detects dead sessions by logging ...
X Description: Summary Fixes #1022. Evict dead Streamable HTTP sessions after repeated keep-alive ping failures. When keep-alive-interval is enabled, KeepAliveScheduler currently detects dead sessions by logging ...
Opengraph URL: https://github.com/modelcontextprotocol/java-sdk/pull/1028
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:ddd460e1-f0c5-ab0d-7c0f-09bfddae83f6 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | C68A:15BB49:21EDC4A:2C91D4C:6A5CA783 |
| html-safe-nonce | 62088586e57f463e7c26e6a49b17806e3717ccddbd763614d4eea083d3a095ae |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDNjhBOjE1QkI0OToyMUVEQzRBOjJDOTFENEM6NkE1Q0E3ODMiLCJ2aXNpdG9yX2lkIjoiNzQ0OTkwMDAzOTc2NTAxMDMwNyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | c3a96a529e29dfc5009618efac63442de516a0159af0b722e143e34b72d0bc75 |
| hovercard-subject-tag | pull_request:3862294167 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/modelcontextprotocol/java-sdk/pull/1028/files |
| twitter:image | https://avatars.githubusercontent.com/u/268150704?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/268150704?s=400&v=4 |
| og:image:alt | Summary Fixes #1022. Evict dead Streamable HTTP sessions after repeated keep-alive ping failures. When keep-alive-interval is enabled, KeepAliveScheduler currently detects dead sessions by logging ... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 5290d7e14309ad1e76106a9c4237bd1041517e83ea182c8ab756752cb0c6940b |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/modelcontextprotocol/java-sdk git https://github.com/modelcontextprotocol/java-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 919609219 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/java-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 919609219 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/java-sdk |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 9c975978430e9ad293956f2bbdaf153b1bd84a99 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width