Fix race condition with mounted server task results

When a server is mounted on another, both were creating their own
Docket and Worker instances. With memory:// URLs they share the same
FakeServer queue but have separate result_storage instances. This
caused a race condition where results could be stored in one Docket's
storage but looked up in another's, returning None.

The fix marks mounted servers with `_is_mounted=True` flag so they
skip creating their own Docket/Worker. The parent's Docket handles
all task execution for mounted servers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Chris Guidry 2025-12-08 13:33:57 -05:00
commit a335a9dd89

View file

@ -201,6 +201,9 @@ class FastMCP(Generic[LifespanResultT]):
self._additional_http_routes: list[BaseRoute] = []
self._mounted_servers: list[MountedServer] = []
self._is_mounted: bool = (
False # Set to True when this server is mounted on another
)
self._tool_manager: ToolManager = ToolManager(
duplicate_behavior=on_duplicate_tools,
mask_error_details=mask_error_details,
@ -395,6 +398,13 @@ class FastMCP(Generic[LifespanResultT]):
server_token = _current_server.set(weakref.ref(self))
try:
# For directly mounted servers, the parent's Docket/Worker handles all
# task execution. Skip creating our own to avoid race conditions with
# multiple workers competing for tasks from the same queue.
if self._is_mounted:
yield
return
# Create Docket instance using configured name and URL
async with Docket(
name=settings.docket.name,
@ -2696,6 +2706,11 @@ class FastMCP(Generic[LifespanResultT]):
if as_proxy and not isinstance(server, FastMCPProxy):
server = FastMCP.as_proxy(server)
# Mark the server as mounted so it skips creating its own Docket/Worker.
# The parent's Docket handles task execution, avoiding race conditions
# with multiple workers competing for tasks from the same queue.
server._is_mounted = True
# Delegate mounting to all three managers
mounted_server = MountedServer(
prefix=prefix,