Reapply "修复菜单插件超时拖慢主链路问题"

This reverts commit 34adefa931.
This commit is contained in:
Liu
2026-05-01 12:45:29 +08:00
parent 994f452b99
commit 47d623e4a4
5 changed files with 51 additions and 11 deletions

View File

@@ -30,6 +30,7 @@ class RobotMenuRenderTool:
image_fallback_to_text: bool,
image_render_timeout_seconds: int,
image_render_retries: int,
sync_send_timeout_seconds: int,
image_template_path: str,
log=default_logger,
):
@@ -40,6 +41,11 @@ class RobotMenuRenderTool:
# 渲染超时与重试参数,统一集中在工具层处理。
self.image_render_timeout_seconds = int(image_render_timeout_seconds)
self.image_render_retries = int(image_render_retries)
# 同步发送超时预算:
# 1. “菜单”属于即时交互命令,不能像离线任务一样长时间占住消息处理协程;
# 2. 因此这里单独维护一个“主链路最多等多久”的预算,超时后立即进入降级逻辑;
# 3. 图片渲染器即便本身还能继续尝试,也不允许把主消息链路拖成几十秒假死。
self.sync_send_timeout_seconds = max(8, int(sync_send_timeout_seconds or 18))
# 注入日志对象,便于主插件统一控制日志风格与输出目标。
self.log = log or default_logger
# 菜单图片模板路径(相对仓库根目录),支持仅改模板文件完成 UI 更新。
@@ -487,7 +493,14 @@ class RobotMenuRenderTool:
md_content = (markdown_content or "").strip() or f"```text\n{text_content}\n```"
output_image = f"robot_menu_{int(time.time() * 1000)}.png"
try:
total_timeout = max(30, self.image_render_timeout_seconds * max(1, self.image_render_retries) + 10)
# 这里故意不再使用“渲染超时 * 重试次数 + 缓冲”的长预算:
# 1. 菜单是即时命令,用户更在意“尽快拿到结果或降级结果”,而不是死等图片;
# 2. 若沿用 45~55 秒预算,多个菜单命令会持续占住机器人并发槽位,放大成“整条插件链路卡住”;
# 3. 因此统一按 sync_send_timeout_seconds 控制主链路等待时间,超时后快速回退。
total_timeout = max(8, int(self.sync_send_timeout_seconds or 18))
# Markdown 转图内部也要用更短预算,避免内外层超时完全重合,导致降级逻辑来不及执行。
html_budget_seconds = max(5, min(10, total_timeout - 4))
render_budget_seconds = max(6, total_timeout - 2)
output_dir = Path(os.getcwd()) / "temp" / "md2image"
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / output_image
@@ -503,8 +516,8 @@ class RobotMenuRenderTool:
md_content,
output_image,
max_retries=max(1, self.image_render_retries),
render_timeout_seconds=max(10, self.image_render_timeout_seconds),
html_timeout_seconds=min(30, max(10, self.image_render_timeout_seconds)),
render_timeout_seconds=render_budget_seconds,
html_timeout_seconds=html_budget_seconds,
),
timeout=total_timeout,
)