feat: 更新命令查找逻辑,支持返回匹配的命名捕获组,并优化旧连接请求处理

This commit is contained in:
DrSmoothl
2026-03-13 10:37:07 +08:00
parent 89bd4ba13a
commit 0d9eff7001
4 changed files with 107 additions and 31 deletions

View File

@@ -181,18 +181,23 @@ class ComponentRegistry:
comps = self._by_plugin.get(plugin_id, [])
return [c for c in comps if c.enabled] if enabled_only else list(comps)
def find_command_by_text(self, text: str) -> Optional[RegisteredComponent]:
"""通过文本匹配命令正则,返回第一个匹配的 command 组件。"""
def find_command_by_text(self, text: str) -> Optional[tuple[RegisteredComponent, Dict[str, Any]]]:
"""通过文本匹配命令正则,返回 (组件, matched_groups) 元组。
matched_groups 为正则命名捕获组 dict别名匹配时为空 dict。
"""
for comp in self._by_type.get("command", {}).values():
if not comp.enabled:
continue
if comp._compiled_pattern and comp._compiled_pattern.search(text):
return comp
if comp._compiled_pattern:
m = comp._compiled_pattern.search(text)
if m:
return comp, m.groupdict()
# 别名匹配
aliases = comp.metadata.get("aliases", [])
for alias in aliases:
if text.startswith(alias):
return comp
return comp, {}
return None
def get_event_handlers(

View File

@@ -225,6 +225,19 @@ class RPCServer:
if old_connection and old_connection is not conn and not old_connection.is_closed:
logger.info("检测到新 Runner 已接管连接,关闭旧连接")
# 新连接接管后,旧 Runner 的 in-flight 请求不会再收到响应
# (过期 generation 响应会被 _handle_response 丢弃),
# 在此处立即 fail-fast 所有 pending 请求,避免挂到超时
stale_count = 0
for _req_id, future in list(self._pending_requests.items()):
if not future.done():
future.set_exception(
RPCError(ErrorCode.E_PLUGIN_CRASHED, "Runner 连接已被新 generation 接管")
)
stale_count += 1
self._pending_requests.clear()
if stale_count:
logger.info(f"已清理 {stale_count} 个旧 Runner 的 pending 请求")
await old_connection.close()
# 启动消息接收循环
@@ -237,7 +250,7 @@ class RPCServer:
self._connection = None
self._runner_id = None
# 连接断开时,立即让所有等待中的请求失败,避免挂起至超时
for req_id, future in list(self._pending_requests.items()):
for _req_id, future in list(self._pending_requests.items()):
if not future.done():
future.set_exception(RPCError(ErrorCode.E_PLUGIN_CRASHED, "Runner 连接已断开"))
self._pending_requests.clear()