[Bug]: MinerU polling ignores cancellation and reports the wait timeout as a missing result

这个报错出现在使用远程 MinerU 解析 PDF 的场景:轮询等待任务结果时没有响应上下文取消,且等待超时后把最后一次状态查询错误原样返回,最终显示为 parser: MinerU result: missing results field 。优先排查 MinerU 轮询逻辑是否缺少 ctx 取消

快速结论:这个报错出现在使用远程 MinerU 解析 PDF 的场景:轮询等待任务结果时没有响应上下文取消,且等待超时后把最后一次状态查询错误原样返回,最终显示为 parser: MinerU result: missing results field。优先排查 MinerU 轮询逻辑是否缺少 ctx 取消检查,以及超时是否被正确区分。

适用环境:Issue 已确认涉及 RAGFlow 的本地 MinerU 客户端路径(MinerULocalModel.ShowTask,由 parsePDFWithMinerU 调用),代码位置为 internal/parser/parser/pdf_parser_mineru.go 中的 pollMinerUTask。Issue 未提供操作系统、Python、CUDA、显卡及具体依赖版本信息。

最快修复方案:暂无确认的一步修复方案。Issue 中已验证的修复是合并 PR #21571:轮询在运行被取消时停止,不再继续等待结果窗口。

注意事项:该修复仅覆盖本地 MinerU 客户端路径;SoMark 异步流程存在相同的单次检查问题,被单独跟踪在 #21076,不在本次修复范围内。Issue 正文中“超时被明确命名并保留最后一次状态错误为 cause”属于期望行为,Issue 讨论摘要未说明该部分是否随 #21571 一并落地,需以实际合并代码为准。

问题场景

用户在 RAGFlow 中使用远程 MinerU 解析 PDF。当 MinerU 兼容服务的 /tasks/{id}/result 在任务运行期间返回 200 {"status":"running"}(不含 results 块)时,pollMinerUTask 会按扫描间隔睡眠后重新检查时间。此时如果取消一次摄入运行(客户端断开、任务取消或服务端关闭),轮询循环不会感知 ctx,会继续调用 ShowTask 并持续睡眠,直到整个 mineru_timeout_seconds 预算耗尽;而预算耗尽后,函数把最后一次 ShowTask 的错误(例如 missing results field)原样返回,导致解析失败信息看起来像结果缺失,而不是等待超时。

报错原文

parser: MinerU result: missing results field

原因分析

最可能的原因是 pollMinerUTask 的轮询实现存在两个缺陷:第一,循环中只检查墙上时钟是否超过 deadline,没有检查上下文是否已取消,因此取消后仍会执行剩余迭代和睡眠;第二,deadline 到达时直接返回 lastErr,而对于仍在运行的任务,ShowTask 会因响应缺少 results 字段而失败,这个状态错误被当作最终结果错误抛出。原本为 nil lastErr 准备的 timed out waiting for MinerU task 分支不可达,因为循环内每条路径都会给 lastErr 赋值,所以等待超时无法被明确识别。

环境排查

  • 确认 RAGFlow 中 mineru_apiserver 指向的 MinerU 兼容服务在任务运行期间返回的响应内容,是否为不含 results 块的 200 {"status":"running"}。
  • 确认当前使用的 RAGFlow 代码是否已包含 PR #21571 的轮询取消修复。
  • 确认解析走的是本地 MinerU 客户端路径(MinerULocalModel.ShowTask / parsePDFWithMinerU),而不是 SoMark 异步流程。
  • 确认 mineru_timeout_seconds 的实际配置值,该值越大,取消后继续轮询造成的占用时间越长。
  • Issue 未提供 Python、PyTorch、CUDA、显卡及依赖版本信息,这些项目无需作为本次排查依据。

解决步骤

  1. 升级或切换到包含 PR #21571 的 RAGFlow 版本。该 PR 已合并,作用是在运行被取消时停止 MinerU 轮询,不再等待结果窗口结束。
  2. 复现验证取消行为:启动一次使用较大 mineru_timeout_seconds 的解析,然后取消上下文,观察调用是否立即返回,而不是等剩余超时耗尽。
  3. 如需完整满足 Issue 期望,检查返回错误是否满足 errors.Is(err, context.Canceled),并确认等待超时是否被明确命名、最后一次状态错误是否作为 cause 保留;若未满足,可优先在 pollMinerUTask 中补充 ctx 检查与超时错误包装。
  4. 对于 SoMark 异步流程中的同类单次检查问题,不要套用本次修复结论,需关注 #21076 的独立处理。

验证方法

按 Issue 复现步骤构造一个在运行期间返回 200 {"status":"running"} 的 MinerU 兼容服务,使用较大的 mineru_timeout_seconds 启动解析并取消上下文:如果修复生效,调用应立即返回,而不是等待剩余超时;对于真正超时的解析,应能明确识别为等待超时,而不是仅得到 parser: MinerU result: missing results field。同时确认取消类错误可通过 errors.Is(err, context.Canceled) 判断。

参考来源

infiniflow/ragflow #21570

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 31415

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注