fix(mcp-bridge): terminate backend process on client disconnect and bound concurrent sessions#13482
Open
shreemaan-abhishek wants to merge 1 commit into
Open
Conversation
…ound concurrent sessions The SSE session loop only ended when a keepalive write failed, which can take two 30s ping cycles or never happen, so a backend process spawned for a disconnected client could stay alive until worker reload. There was also no ceiling on concurrent sessions, so a route could keep spawning backend processes for as many connections as were opened. - register an ngx.on_abort handler so a client disconnect stops the session promptly instead of waiting for the next keepalive write to fail - make the ping loop wake early once the session is asked to stop - always run teardown (process + broker) and free the session slot via a guarded path, regardless of how the loop ended - add a per-worker concurrent-session ceiling (max_sessions, default 100); excess SSE connections get 429 - enable lua_check_client_abort in the main http block so on_abort works Behaviour change: lua_check_client_abort is now on globally, so long-running Lua handler phases are terminated when the client disconnects (proxied requests were already aborted by nginx). New config field max_sessions.
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.
Description
The
mcp-bridgeplugin spawns a backend process per SSE connection and relies on the SSE session loop returning to tear that process down. Today the loop only ends when a keepalive write fails, which can take up to two 30s ping cycles or, if writes keep being absorbed by the connection, may not happen at all. As a result a backend process started for a client that has already gone away can stay alive until the worker reloads. Separately, there is no ceiling on how many sessions a worker will keep open, so a route can keep spawning backend processes for as many connections as are opened.This PR makes session teardown deterministic and bounds concurrency:
ngx.on_aborthandler so a client disconnect stops the session promptly instead of waiting for the next keepalive write to fail.max_sessionsconfig field (default100); connections beyond the ceiling get429.lua_check_client_abortin the mainhttpblock soon_abortis usable.The concurrent-session bookkeeping is factored into a small
apisix/plugins/mcp/session_limit.luamodule so it can be unit-tested.Behaviour changes
lua_check_client_abortis now enabled globally in the mainhttpblock. This means long-running Lua handler phases are terminated when the client disconnects. Proxied requests were already aborted by nginx in this case, so the practical effect is limited to Lua streaming handlers, which now stop work when the client goes away.max_sessions(integer, default100). Existing configs keep working unchanged; the default applies when the field is omitted.Which issue(s) this PR fixes:
Fixes #
Checklist