2.1 KiB
2.1 KiB
[bug] MCP start_article_summary_job 超时但 job 实际执行了
问题描述
连续多个 start_article_summary_job 调用报 MCP 超时(-32001 Request timed out),但 job 实际执行了:
run_state.json显示status: failed,current_stage: generate_markdown- job 目录正常生成,
run-state.json存在于outputs/freshrss/article_summary_jobs/<job-id>/ generate_markdown阶段实际执行过(有结果),但 MCP 响应没能发回来
根因分析
server.py 的 start_article_summary_job handler 用同步方式处理请求:
proc = subprocess.Popen(
cmd,
cwd=str(REPO_ROOT),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True,
)
# ← Popen 返回后,server 主进程在发送 stdio 响应前被阻塞
return {
"job_id": job_id,
"status": "running",
...
} # ← 这里应该立即返回,但可能被某种同步操作卡住
job 启动流程本身没问题(subprocess 确实被启动并执行了),问题出在 MCP server 发送响应的环节。
可能的阻塞点:
store.save()或store.finish_stage()涉及的磁盘锁- stdio 响应的序列化或写入
- MCP server 的某种并发控制
修复方向
将 job 启动改造为真正的非阻塞模式:
- 方案 A(推荐): 用后台线程/线程池(
concurrent.futures.ThreadPoolExecutor)启动 job runner,主线程立即返回响应 - 方案 B: 改用纯异步模式,job 状态完全通过
get_article_summary_job_status查询
正确处理(临时 workaround)
当 MCP 调用 start_article_summary_job 超时后,不应立即判定 job 失败:
- 调用
get_article_summary_job_status(job_id)查询真实状态 - 若返回
status=running或run_state.json存在且status=running→ job 在跑,继续等待 - 若返回
status=failed→ 查run_state.json的failed_stage和error_summary
影响范围
- OpenClaw MCP 客户端调用
start_article_summary_job - 任何通过 stdio MCP 通道使用 article summary job 的场景
复现时间
2026-04-16