FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix: memory leak and exit problems by PWZER · Pull Request #586 · modelcontextprotocol/python-sdk · GitHub

Repository navigation

Fix: memory leak and exit problems - #586

Closed
PWZER wants to merge 5 commits into
modelcontextprotocol:mainfrom
PWZER:main
Closed

PWZER wants to merge 5 commits into
modelcontextprotocol:mainfrom
PWZER:main

Conversation

PWZER commented Apr 25, 2025 •
edited
Loading

Copy link
Copy Markdown

Motivation and Context

  • Here handle_sse calls app.run() every time it processes a sse request, but app.run() keeps running and does not stop automatically, which causes handle_sse to never end, and finally causes a memory leak.

    async def handle_sse(request):
    async with sse.connect_sse(
    request.scope, request.receive, request._send
    ) as streams:
    await app.run(
    streams[0], streams[1], app.create_initialization_options()
    )

  • And this is also the key reason for the following exit problems issues#541, Fixed.

    INFO:     Waiting for background tasks to complete. (CTRL+C to force quit)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Comment thread pyproject.toml
"pydantic>=2.7.2,<3.0.0",
"starlette>=0.27",
"sse-starlette>=1.6.1",
"sse-starlette>=2.3.0",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Is this needed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yes, sse-starlette supports client_close_handler_callable since version 2.3.0.

ihrpr added this to the 2025-03-26 spec release milestone Apr 28, 2025

Copy link
Copy Markdown

This looks great, Thanks @PWZER

ihrpr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Unfortunately we can't upgrade sse-starlette in SDK now.

We can achieve similar functionality as client_close_handler_callable provides in this case by using disconnect_listener

Something like this should work:

 async with anyio.create_task_group() as tg:
            response = EventSourceResponse(
                content=sse_stream_reader,
                data_sender_callable=sse_writer,
            )

            async def disconnect_listener():
                try:
                    await response.listen_for_disconnect(receive)
                    logger.error(f"Disconnect detected for session: {session_id}")
                    await client_close_handler()  # defined earlier in the PR - name should be changed probably
                except Exception as e:
                    logger.error(f"Error in disconnect listener: {e}")

            tg.start_soon(disconnect_listener)
            logger.debug("Starting SSE response task")
            tg.start_soon(response, scope, receive, send)

            ...
            yield (read_stream, write_stream)

Comment thread src/mcp/server/sse.py
async def client_close_handler(message: Message) -> None:
await read_stream_writer.aclose()
await write_stream_reader.aclose()
del self._read_stream_writers[session_id]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
del self._read_stream_writers[session_id]
self._read_stream_writers.pop(session_id, None)

Comment thread src/mcp/server/sse.py
scope: Scope,
receive: Receive,
send: Send,
callback: Callable[[], None] | None = None,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

The callback function only is called when client connection close so the naming is not full-meaning . And I don't think it should callback here because connect_sse yield

ihrpr commented Jul 8, 2025

Copy link
Copy Markdown
Contributor

Closing this PR as stale. We can't update sse-starlette for now.

Thank you for your contribution and working on improving this project.

ihrpr closed this Jul 8, 2025
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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants


Back | FazBrowse Home | New Git URL