OCR:确定性坏输入的 HTTP 500 被归为瞬时错误,重试并计入熔断(parse_layout / recognize_text) #35
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
#34 的设计调研(research-wiki/designs/2026-10-21-issue34-ocr-document-design.md §6)发现,MonkeyOCR 服务对所有确定性的坏输入都返回 HTTP 500,响应体形如
{"detail":"Parsing failed: <原因>"}。2026-10-21 在真实服务上实测:Parsing failed: cannot save with zero pages%PDF-头:Parsing failed: Failed to open streamParsing failed: Failed to open streamParsing failed: Cannot open empty streamParsing failed: is no PDF服务端
api/main.py:501-503把一切异常(包括它自己抛的 400)都包成500 "Parsing failed: ..."。现状与后果
transports/monkey_ocr.py:96-97的_classify_status对status >= 500一律归TransientError。于是一张损坏的图片会:重试max_attempts次、每次计入熔断失败、并喂给选源器失败。默认配置下熔断的连续失败通道在窗口样本不足(
min_calls=10)或失败率 ≥ 0.6 时会开路,有效阈值是max(配置值, 源并发×2)。低并发配置下,一两张坏图就可能把该 scope 的熔断打开,冷却期内同 scope 的正常调用被fail_fast拒绝。本 issue 要决定的
#34 只在新增的
parse_document路径上做了窄化(对一组已知的确定性标记改归RequestRejectedError,保留status_code=500,熔断记成功不计窗口),既有的parse_layout/recognize_text行为没有动,因为这会改变医院线对坏图的重试与熔断行为,属公共行为变更。需要评估:是否把同样的窄化推广到共享的
_classify_status,以及是否需要一个可配置的标记集合。注意标记是 PyMuPDF 的界面文案,会随服务版本漂移;Parsing failed:前缀本身不能作为判据(服务会把Model not initialized之类的真故障也包成同一前缀)。需走 brainstorming。