Skip to content

Commit 1e93ce4

Browse files
committed
refactor: reuse mcp cleanup and client view
1 parent ef8e254 commit 1e93ce4

1 file changed

Lines changed: 30 additions & 19 deletions

File tree

astrbot/core/provider/func_tool_manager.py

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,22 @@ class _MCPServerRuntime:
6565
lifecycle_task: asyncio.Task[None]
6666

6767

68+
class _MCPClientDictView(Mapping[str, MCPClient]):
69+
"""Read-only view of MCP clients derived from runtime state."""
70+
71+
def __init__(self, runtime: dict[str, _MCPServerRuntime]) -> None:
72+
self._runtime = runtime
73+
74+
def __getitem__(self, key: str) -> MCPClient:
75+
return self._runtime[key].client
76+
77+
def __iter__(self):
78+
return iter(self._runtime)
79+
80+
def __len__(self) -> int:
81+
return len(self._runtime)
82+
83+
6884
def _resolve_timeout(
6985
timeout: float | int | str | None = None,
7086
*,
@@ -194,6 +210,7 @@ def __init__(self) -> None:
194210
self._mcp_server_runtime: dict[str, _MCPServerRuntime] = {}
195211
"""MCP 服务运行时状态(唯一事实来源)"""
196212
self._mcp_server_runtime_view = MappingProxyType(self._mcp_server_runtime)
213+
self._mcp_client_dict_view = _MCPClientDictView(self._mcp_server_runtime)
197214
self._timeout_mismatch_warned = False
198215
self._timeout_warn_lock = threading.Lock()
199216
self._runtime_lock = asyncio.Lock()
@@ -219,9 +236,7 @@ def mcp_client_dict(self) -> Mapping[str, MCPClient]:
219236
220237
Note: Mutating this mapping is unsupported and will raise TypeError.
221238
"""
222-
return MappingProxyType(
223-
{name: runtime.client for name, runtime in self._mcp_server_runtime.items()}
224-
)
239+
return self._mcp_client_dict_view
225240

226241
@property
227242
def mcp_server_runtime_view(self) -> Mapping[str, _MCPServerRuntime]:
@@ -596,22 +611,18 @@ async def _terminate_mcp_client(self, name: str) -> None:
596611
runtime = self._mcp_server_runtime.get(name)
597612
if runtime:
598613
client = runtime.client
599-
try:
600-
# 关闭MCP连接
601-
await client.cleanup()
602-
except Exception as e:
603-
logger.error(f"清空 MCP 客户端资源 {name}: {e}。")
604-
finally:
605-
# 移除关联的FuncTool
606-
self.func_list = [
607-
f
608-
for f in self.func_list
609-
if not (isinstance(f, MCPTool) and f.mcp_server_name == name)
610-
]
611-
async with self._runtime_lock:
612-
self._mcp_server_runtime.pop(name, None)
613-
self._mcp_starting.discard(name)
614-
logger.info(f"已关闭 MCP 服务 {name}")
614+
# 关闭MCP连接
615+
await self._cleanup_mcp_client_safely(client, name)
616+
# 移除关联的FuncTool
617+
self.func_list = [
618+
f
619+
for f in self.func_list
620+
if not (isinstance(f, MCPTool) and f.mcp_server_name == name)
621+
]
622+
async with self._runtime_lock:
623+
self._mcp_server_runtime.pop(name, None)
624+
self._mcp_starting.discard(name)
625+
logger.info(f"已关闭 MCP 服务 {name}")
615626
return
616627

617628
# Runtime missing but stale tools may still exist after failed flows.

0 commit comments

Comments
 (0)