修复 EasyOCR 连续启动失败不触发重启的问题:
- 新增 _easyocr_consecutive_startup_failures 计数器,跟踪子进程无法启动的次数 - 当连续3次启动失败时,清除冷却时间并重置状态,强制重试启动 - 前2次保留冷却(预留初始化时间),第3次强制清除冷却 - 在所有重置 _easyocr_consecutive_failures 的地方同步重置启动失败计数 - 解决 EasyOCR 全程未启动但从未触发杀进程重启的问题
This commit is contained in:
+24
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user