From 490d4ee45fda0b91574ed846981893e7da987706 Mon Sep 17 00:00:00 2001 From: leweng Date: Wed, 16 Jul 2025 16:43:44 +0800 Subject: [PATCH] fix: replace threading.Lock with anyio.Lock for Ray deployment compatibility - Replace threading.Lock() with anyio.Lock() in StreamableHTTPSessionManager - This resolves serialization issues when deploying StreamableHTTP services with Ray - threading.Lock objects cannot be pickled/serialized, causing deployment failures - anyio.Lock provides equivalent functionality while being fully serializable - Update lock usage from 'with' to 'async with' for proper async context --- src/mcp/server/streamable_http_manager.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mcp/server/streamable_http_manager.py b/src/mcp/server/streamable_http_manager.py index f38e6afec..53d542d21 100644 --- a/src/mcp/server/streamable_http_manager.py +++ b/src/mcp/server/streamable_http_manager.py @@ -4,7 +4,6 @@ import contextlib import logging -import threading from collections.abc import AsyncIterator from http import HTTPStatus from typing import Any @@ -75,7 +74,7 @@ def __init__( # The task group will be set during lifespan self._task_group = None # Thread-safe tracking of run() calls - self._run_lock = threading.Lock() + self._run_lock = anyio.Lock() self._has_started = False @contextlib.asynccontextmanager @@ -97,7 +96,7 @@ async def lifespan(app: Starlette) -> AsyncIterator[None]: yield """ # Thread-safe check to ensure run() is only called once - with self._run_lock: + async with self._run_lock: if self._has_started: raise RuntimeError( "StreamableHTTPSessionManager .run() can only be called "