校验唯一任务添加时间

优化续约代办请求次数
This commit is contained in:
2026-01-04 13:44:53 +08:00
parent 3e4e2c8f41
commit 2528a2778c
7 changed files with 141 additions and 39 deletions
+37 -29
View File
@@ -15,7 +15,7 @@ logger = configure_task_logger()
# 获取错误任务日志记录器
error_task_logger = configure_error_task_logger()
# 全局任务字典,使用 unique_id 作为键
# 全局任务字典,使用 (unique_id, exec_time) 作为组合键,支持一个任务多个执行时间
all_tasks = {}
@@ -86,14 +86,14 @@ class PersistentQueue:
"""将任务加入队列并保存到磁盘"""
self.queue.put(task)
self.save_to_disk()
logger.info(f"任务 {task['unique_id']} 已加入队列。")
logger.info(f"任务 {task['unique_id']} ({task['exec_time']}) 已加入队列。")
def get(self):
"""从队列中获取任务并保存到磁盘"""
if not self.queue.empty():
task = self.queue.get()
self.save_to_disk()
logger.info(f"任务 {task['unique_id']} 已从队列中取出。")
logger.info(f"任务 {task['unique_id']} ({task['exec_time']}) 已从队列中取出。")
return task
else:
logger.info("任务队列为空。")
@@ -120,19 +120,20 @@ task_queue = PersistentQueue()
def load_tasks_and_execute():
"""
从 tasks.csv 文件中加载任务到持久化队列中,仅包含待执行任务。
避免重复添加任务。
支持一个任务多个执行时间,避免重复添加任务。
"""
try:
load_tasks_from_csv() # 从 CSV 文件加载所有任务
now = datetime.now()
# 获取队列中已有任务ID避免重复添加)
existing_task_ids = set()
# 获取队列中已有任务标识(使用 (unique_id, exec_time) 避免重复添加)
existing_task_keys = set()
# 创建一个临时队列来遍历任务
temp_queue = Queue()
while not task_queue.empty():
task = task_queue.get()
existing_task_ids.add(task['unique_id'])
task_key = (task['unique_id'], task['exec_time'])
existing_task_keys.add(task_key)
temp_queue.put(task)
# 将任务放回原队列
while not temp_queue.empty():
@@ -144,18 +145,21 @@ def load_tasks_and_execute():
if (now - exec_time_today) > timedelta(minutes=5):
if task['status'] == '待执行':
error_task_logger.error(f"任务 {task['unique_id']} 超过执行窗口5分钟以上,标记为过期。")
update_task_status(task['unique_id'], '过期')
error_task_logger.error(f"任务 {task['unique_id']} ({task['exec_time']}) 超过执行窗口5分钟以上,标记为过期。")
update_task_status(task['unique_id'], task['exec_time'], '过期')
continue # 不处理过期任务
# 使用组合键判断任务是否已在队列中
task_key = (task['unique_id'], task['exec_time'])
# 如果任务应该执行、状态是待执行且不在队列中
if (task['should_execute'](now) and
task['status'] == '待执行' and
task['unique_id'] not in existing_task_ids):
task_key not in existing_task_keys):
task_queue.put(task)
existing_task_ids.add(task['unique_id'])
logger.info(f"任务 {task['unique_id']} 加入队列。")
existing_task_keys.add(task_key)
logger.info(f"任务 {task['unique_id']} ({task['exec_time']}) 加入队列。")
except Exception as e:
error_task_logger.error(f"加载任务时出错: {e}")
@@ -165,26 +169,26 @@ def load_tasks_and_execute():
def execute_single_task():
"""从队列中取出并执行单个任务"""
"""从队列中取出并执行单个任务,支持一个任务多个执行时间"""
if not task_queue.empty():
try:
task = task_queue.get()
if task:
# 标记任务为正在执行
update_task_status(task['unique_id'], '正在执行')
update_task_status(task['unique_id'], task['exec_time'], '正在执行')
try:
success = execute_task(task['unique_id'])
if success:
update_task_status(task['unique_id'], '已完成')
logger.info(f"任务 {task['unique_id']} 执行成功。")
update_task_status(task['unique_id'], task['exec_time'], '已完成')
logger.info(f"任务 {task['unique_id']} ({task['exec_time']}) 执行成功。")
else:
update_task_status(task['unique_id'], '失败')
error_task_logger.error(f"任务 {task['unique_id']} 执行失败。")
update_task_status(task['unique_id'], task['exec_time'], '失败')
error_task_logger.error(f"任务 {task['unique_id']} ({task['exec_time']}) 执行失败。")
except Exception as e:
error_task_logger.error(f"任务 {task['unique_id']} 执行时发生异常: {e}")
update_task_status(task['unique_id'], '失败')
error_task_logger.error(f"任务 {task['unique_id']} ({task['exec_time']}) 执行时发生异常: {e}")
update_task_status(task['unique_id'], task['exec_time'], '失败')
task_queue.task_done()
@@ -193,7 +197,7 @@ def execute_single_task():
def load_tasks_from_csv():
"""从 tasks.csv 文件中加载任务到全局任务字典"""
"""从 tasks.csv 文件中加载任务到全局任务字典,支持一个任务多个执行时间"""
try:
csv_file = Path('tasks.csv')
if csv_file.is_file():
@@ -212,7 +216,9 @@ def load_tasks_from_csv():
exec_time = datetime.strptime(task['exec_time'], '%H:%M').time()
task['should_execute'] = lambda now, et=exec_time: now.time() >= et
all_tasks[task['unique_id']] = task
# 使用 (unique_id, exec_time) 作为组合键,支持一个任务多个执行时间
task_key = (task['unique_id'], task['exec_time'])
all_tasks[task_key] = task
logger.info("任务已从磁盘加载到全局任务字典。")
else:
logger.warning("tasks.csv 文件未找到,初始化为空任务字典。")
@@ -221,11 +227,12 @@ def load_tasks_from_csv():
def save_tasks_to_csv():
"""将所有任务的状态保存到 tasks.csv 文件"""
"""将所有任务的状态保存到 tasks.csv 文件,支持一个任务多个执行时间"""
try:
with open('tasks.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['unique_id', 'exec_time', 'is_switch_on', 'status'])
writer.writeheader()
# 遍历所有任务实例(包括相同unique_id的不同exec_time
for task in all_tasks.values():
task_to_save = {
'unique_id': task['unique_id'],
@@ -240,14 +247,15 @@ def save_tasks_to_csv():
error_task_logger.error(f"保存任务状态时出错: {e}")
def update_task_status(task_id, new_status):
"""更新指定任务的状态,并保存到磁盘"""
if task_id in all_tasks:
all_tasks[task_id]['status'] = new_status
def update_task_status(task_id, exec_time, new_status):
"""更新指定任务的状态,并保存到磁盘,支持一个任务多个执行时间"""
task_key = (task_id, exec_time)
if task_key in all_tasks:
all_tasks[task_key]['status'] = new_status
save_tasks_to_csv()
logger.info(f"任务 {task_id} 状态已更新为 {new_status}")
logger.info(f"任务 {task_id} ({exec_time}) 状态已更新为 {new_status}")
else:
error_task_logger.error(f"尝试更新不存在的任务 {task_id} 的状态。")
error_task_logger.error(f"尝试更新不存在的任务 {task_id} ({exec_time}) 的状态。")
def load_tasks_on_start():