强化EasyOCR超时计数:锁竞争超时/内层超时/外层超时/BrokenPipe均计入consecutive_failures+重置call_count,防'3次超时却正常释放'误触发

This commit is contained in:
youpaishidifu
2026-08-06 14:28:33 +08:00
parent 37ce6a0916
commit 88593898be
+15
View File
@@ -1832,6 +1832,13 @@ class MessageMonitor:
# 改为带超时 acquire,超时即放弃本次请求(下轮重试),线程正常结束释放大图。
if not self._easyocr_lock.acquire(timeout=15.0):
logger.warning("[ocr] EasyOCR 锁竞争超时(15s),放弃本次请求(防线程永久阻塞致内存泄漏)")
# ⭐ 锁竞争超时也计入连续失败 + 重置call_count(防"正常释放"误触发)
self._easyocr_consecutive_failures += 1
self._easyocr_call_count = 0 # 中断连续成功计数
if self._easyocr_consecutive_failures >= self._easyocr_max_failures:
logger.warning(f"[ocr] EasyOCR 连续{self._easyocr_consecutive_failures}次异常(含锁竞争),杀子进程重来")
self._kill_easyocr_proc("连续异常(含锁竞争)")
self._easyocr_consecutive_failures = 0
return None
try:
# ⚠ 竞态保护:另一个线程可能已杀死进程并设 None
@@ -1867,6 +1874,9 @@ class MessageMonitor:
logger.debug("[ocr] EasyOCR 等待期间急停,丢弃未出结果的 OCR 请求")
else:
self._easyocr_consecutive_failures += 1
if self._easyocr_call_count > 0:
logger.debug(f"[ocr] EasyOCR 超时重置call_count: {self._easyocr_call_count}→0(防'正常释放'误触发)")
self._easyocr_call_count = 0 # ⭐ 超时重置call_count,防"正常释放"误触发
if self._easyocr_consecutive_failures >= self._easyocr_max_failures:
logger.debug(f"[ocr] EasyOCR 连续{self._easyocr_consecutive_failures}次超时,杀子进程重来")
self._kill_easyocr_proc("连续超时")
@@ -1915,10 +1925,14 @@ class MessageMonitor:
except (BrokenPipeError, ConnectionError, OSError) as e:
logger.debug(f"[ocr] EasyOCR 子进程通信断开: {e},30s 后自动重试")
self._easyocr_proc = None
self._easyocr_call_count = 0 # 进程死了,重置call_count
self._easyocr_consecutive_failures += 1
self._easyocr_retry_until = time.time() + 30 # 冷却后自动重试,不永久 broken
return None
except Exception as e:
logger.debug(f"[ocr] EasyOCR 子进程异常: {e}")
self._easyocr_call_count = 0
self._easyocr_consecutive_failures += 1
return None
@staticmethod
@@ -2181,6 +2195,7 @@ class MessageMonitor:
logger.warning(f"[{platform}] EasyOCR 超时({_OCR_TIMEOUT}s)线程存活,跳过")
# ⭐ EasyOCR线程超时也计入连续失败,防止"超时跳过"绕过杀进程逻辑
self._easyocr_consecutive_failures += 1
self._easyocr_call_count = 0 # ⭐ 超时重置call_count,防"正常释放"误触发
if self._easyocr_consecutive_failures >= self._easyocr_max_failures:
logger.warning(f"[{platform}] EasyOCR 连续{self._easyocr_consecutive_failures}次超时,杀子进程重来")
self._kill_easyocr_proc("双引擎连续超时")