修复 EasyOCR 连续启动失败不触发重启的问题:

- 新增 _easyocr_consecutive_startup_failures 计数器,跟踪子进程无法启动的次数
- 当连续3次启动失败时,清除冷却时间并重置状态,强制重试启动
- 前2次保留冷却(预留初始化时间),第3次强制清除冷却
- 在所有重置 _easyocr_consecutive_failures 的地方同步重置启动失败计数
- 解决 EasyOCR 全程未启动但从未触发杀进程重启的问题
This commit is contained in:
youpaishidifu
2026-08-03 22:34:22 +08:00
parent 795a245de7
commit d6691f6037
+24
View File
@@ -353,6 +353,9 @@ class MessageMonitor:
# EasyOCR 连续失败计数:前2次保留子进程(预留初始化时间),第3次杀进程重来
self._easyocr_consecutive_failures: int = 0
self._easyocr_max_failures: int = 3 # 连续3次失败后杀进程
# EasyOCR 连续启动失败计数:子进程无法启动时递增,达到阈值时清除冷却重试
self._easyocr_consecutive_startup_failures: int = 0
self._easyocr_max_startup_failures: int = 3 # 连续3次启动失败后清除冷却
# EasyOCR CUDA 错误计数:≥2 次 OOM/kernel error → 下次启动强制 CPU(防冻结)
self._easyocr_cuda_oom_count: int = 0
# 引擎选择计数器
@@ -420,6 +423,7 @@ class MessageMonitor:
self._easyocr_retry_until = 0.0 # 清除崩溃冷却
self._easyocr_call_count = 0
self._easyocr_consecutive_failures = 0 # ⭐ 清除连续超时计数(stop/急停后不残留)
self._easyocr_consecutive_startup_failures = 0 # ⭐ 清除连续启动失败计数
# ⭐ 彻底重启时重新检测内存,尝试恢复GPU模式
# 急停/手动停止恢复时保持上次状态,不重新检测
@@ -491,6 +495,7 @@ class MessageMonitor:
self._easyocr_retry_until = 0.0 # 清除崩溃冷却
self._easyocr_call_count = 0
self._easyocr_consecutive_failures = 0 # ⭐ 清除连续超时计数(stop/急停后不残留)
self._easyocr_consecutive_startup_failures = 0 # ⭐ 清除连续启动失败计数
self._easyocr_cuda_oom_count = 0 # 重启后重新评估 GPU/CPU
# 释放钩子回调引用(防止 GC 延迟导致卸载后崩溃)
@@ -658,6 +663,7 @@ class MessageMonitor:
self._easyocr_retry_until = 0.0 # 清除崩溃冷却
self._easyocr_call_count = 0
self._easyocr_consecutive_failures = 0 # 清除连续超时计数
self._easyocr_consecutive_startup_failures = 0 # 清除连续启动失败计数
self._easyocr_cuda_oom_count = 0 # 清除 CUDA 错误计数(不继承本次降级)
self._last_screenshot_hash.clear()
self._ocr_unchanged.clear()
@@ -1498,6 +1504,7 @@ class MessageMonitor:
payload = json.loads(line)
if payload.get("ready"):
logger.debug("[ocr] EasyOCR 子进程就绪")
self._easyocr_consecutive_startup_failures = 0 # 成功启动,重置启动失败计数
return True
except Exception:
pass
@@ -1529,6 +1536,21 @@ class MessageMonitor:
import base64
if not self._ensure_easyocr_subprocess():
# ⭐ 连续启动失败计数:子进程无法启动时递增,达到阈值时清除冷却重试
self._easyocr_consecutive_startup_failures += 1
if self._easyocr_consecutive_startup_failures >= self._easyocr_max_startup_failures:
logger.warning(f"[ocr] EasyOCR 连续{self._easyocr_consecutive_startup_failures}次启动失败,"
f"清除冷却({int(self._easyocr_retry_until - time.time())}s)并重置状态,强制重试")
# 清除冷却时间,强制重试启动
self._easyocr_retry_until = 0.0
# 重置进程状态
self._easyocr_proc = None
self._easyocr_broken = False
# 重置计数器(避免无限循环)
self._easyocr_consecutive_startup_failures = 0
else:
logger.debug(f"[ocr] EasyOCR 第{self._easyocr_consecutive_startup_failures}次启动失败,"
f"保留冷却({int(self._easyocr_retry_until - time.time())}s)")
return None
try:
@@ -1581,6 +1603,7 @@ class MessageMonitor:
pass
self._easyocr_proc = None
self._easyocr_consecutive_failures = 0
self._easyocr_consecutive_startup_failures = 0 # 重置启动失败计数
else:
logger.debug(f"[ocr] EasyOCR 第{self._easyocr_consecutive_failures}次超时({timeout}s),保留子进程不杀")
return None
@@ -1596,6 +1619,7 @@ class MessageMonitor:
if result.get("ok"):
# 成功 → 重置连续失败计数
self._easyocr_consecutive_failures = 0
self._easyocr_consecutive_startup_failures = 0 # 成功启动,重置启动失败计数
# 计数 + 主动重启:EasyOCR GPU 内存泄漏累积 → OOM → 冻结
self._easyocr_call_count += 1
if self._easyocr_call_count >= self._easyocr_max_calls: