Files
reader/issues/mcp-timeout-job-running.md
T

61 lines
2.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# [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 用同步方式处理请求:
```python
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 发送响应的环节**。
可能的阻塞点:
1. `store.save()` 或 `store.finish_stage()` 涉及的磁盘锁
2. stdio 响应的序列化或写入
3. MCP server 的某种并发控制
## 修复方向
将 job 启动改造为真正的非阻塞模式:
- **方案 A(推荐):** 用后台线程/线程池(`concurrent.futures.ThreadPoolExecutor`)启动 job runner,主线程立即返回响应
- **方案 B:** 改用纯异步模式,job 状态完全通过 `get_article_summary_job_status` 查询
## 正确处理(临时 workaround)
当 MCP 调用 `start_article_summary_job` 超时后,不应立即判定 job 失败:
1. 调用 `get_article_summary_job_status(job_id)` 查询真实状态
2. 若返回 `status=running` 或 `run_state.json` 存在且 `status=running` → job 在跑,继续等待
3. 若返回 `status=failed` → 查 `run_state.json` 的 `failed_stage` 和 `error_summary`
## 影响范围
- OpenClaw MCP 客户端调用 `start_article_summary_job`
- 任何通过 stdio MCP 通道使用 article summary job 的场景
## 复现时间
2026-04-16