From c180129a1af34df1f308c0d58d1f1bc8f94cb4cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Tue, 21 Jul 2026 11:29:06 +0800 Subject: [PATCH] fix: add SIGALRM 120s hard timeout to price_monitor lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit price_monitor.py 进程锁无硬超时,LLM策略重评耗时9-10分钟时 锁文件阻止后续*/2 cron执行,造成10分钟监控盲区。 新增: - _handle_sigalrm: SIGALRM处理器,自动清理锁后退出 - signal.alarm(120): 获锁后设120s硬上限 - signal.alarm(0): 正常完成时取消定时器 --- deploy/profile-scripts/price_monitor.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/deploy/profile-scripts/price_monitor.py b/deploy/profile-scripts/price_monitor.py index 652e1d9e..b5159d11 100644 --- a/deploy/profile-scripts/price_monitor.py +++ b/deploy/profile-scripts/price_monitor.py @@ -407,10 +407,17 @@ def _handle_sigterm(signum, frame): _cleanup_lock() sys.exit(0) +def _handle_sigalrm(signum, frame): + """收到SIGALRM强制超时时清理锁文件后退出""" + _cleanup_lock() + print(f"[TIMEOUT] 本轮执行超时({signum}s),已清理锁文件", file=sys.stderr, flush=True) + sys.exit(0) + def run_once(round_label=""): """执行一轮完整的监控流程""" import os, signal # 必须在开头import,否则os变量会被后面的局部import绑定覆盖 signal.signal(signal.SIGTERM, _handle_sigterm) + signal.signal(signal.SIGALRM, _handle_sigalrm) os.nice(10) # 降低优先级,避免与DB其他写操作抢占 # ── 进程锁:同一时间只跑一个实例 ── _lk = "/tmp/price_monitor.lock" @@ -425,6 +432,7 @@ def run_once(round_label=""): pass with open(_lk, "w") as _f: _f.write(str(os.getpid())) + signal.alarm(120) # 硬上限120s,超时自动清理锁退出 label = f" [{round_label}]" if round_label else "" start = time.time() @@ -745,6 +753,9 @@ def run_once(round_label=""): # 输出耗时 print(f"⏱{label} {elapsed:.1f}s", flush=True) + # 取消超时定时器(正常完成) + signal.alarm(0) + # 清理进程锁 try: os.remove("/tmp/price_monitor.lock")