复查修复(三): 调度与扫描
- scan: .tmp/.part 过滤 + list_files 分批遍历(消除 10 万条截断误判) - Scheduler: 持锁只做标记, 锁外异步执行任务(长任务不再冻结调度) - cron 范围/步进边界校验;FTP 下载后大小校验防静默截断
This commit is contained in:
+25
-9
@@ -103,16 +103,27 @@ class ScheduledTask:
|
||||
result.extend(self._parse_cron_part(sub.strip(), min_val, max_val))
|
||||
return result
|
||||
|
||||
# 处理范围: "1-5"
|
||||
# 处理范围: "1-5"(校验边界,越界返回空)
|
||||
if '-' in part:
|
||||
start, end = part.split('-')
|
||||
return list(range(int(start), int(end) + 1))
|
||||
try:
|
||||
start, end = part.split('-')
|
||||
start, end = int(start), int(end)
|
||||
if not (min_val <= start <= end <= max_val):
|
||||
return []
|
||||
return list(range(start, end + 1))
|
||||
except ValueError:
|
||||
return []
|
||||
|
||||
# 处理步进: "*/5"
|
||||
if '/' in part:
|
||||
base, step = part.split('/')
|
||||
base_list = self._parse_cron_part(base or '*', min_val, max_val)
|
||||
step = int(step)
|
||||
try:
|
||||
step = int(step)
|
||||
if step <= 0:
|
||||
return []
|
||||
except ValueError:
|
||||
return []
|
||||
return base_list[::step]
|
||||
|
||||
# 单个值
|
||||
@@ -301,18 +312,23 @@ class Scheduler:
|
||||
logger.info("定时任务调度器已停止")
|
||||
|
||||
def _run_loop(self):
|
||||
"""运行循环"""
|
||||
"""运行循环(持锁只做标记,锁外异步执行任务,避免长任务冻结调度)"""
|
||||
while self._running:
|
||||
try:
|
||||
now = datetime.now()
|
||||
|
||||
due = []
|
||||
with self._lock:
|
||||
for name, task in self.tasks.items():
|
||||
if task.should_run_now():
|
||||
# 使用线程池执行任务
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
with ThreadPoolExecutor(max_workers=1) as executor:
|
||||
executor.submit(task.run)
|
||||
due.append(task)
|
||||
|
||||
# 锁外异步执行,不阻塞后续任务的调度
|
||||
for task in due:
|
||||
try:
|
||||
threading.Thread(target=task.run, daemon=True).start()
|
||||
except Exception as e:
|
||||
logger.error(f"调度任务 {task.name} 启动失败: {e}")
|
||||
|
||||
time.sleep(self.check_interval)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user