diff --git a/app.py b/app.py index 2779ec4..6268116 100755 --- a/app.py +++ b/app.py @@ -23,6 +23,7 @@ import threading import time import json import os +import sys import secrets # 安全修复: 使用加密安全的随机数生成 from datetime import datetime, timedelta, timezone from functools import wraps @@ -1942,9 +1943,14 @@ def get_user_semaphore(user_id): return user_semaphores[user_id] -def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="manual"): - """运行自动化任务""" - print(f"[DEBUG run_task] account={account_id}, enable_screenshot={enable_screenshot} (类型:{type(enable_screenshot).__name__}), source={source}") +def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="manual", retry_count=0): + """运行自动化任务 + + Args: + retry_count: 当前重试次数,用于自动重试机制(最多重试2次) + """ + MAX_AUTO_RETRY = 2 # 最大自动重试次数 + print(f"[DEBUG run_task] account={account_id}, enable_screenshot={enable_screenshot} (类型:{type(enable_screenshot).__name__}), source={source}, retry={retry_count}") if user_id not in user_accounts or account_id not in user_accounts[user_id]: return @@ -2399,10 +2405,30 @@ def run_task(user_id, account_id, browse_type, enable_screenshot=True, source="m socketio.emit('account_update', account.to_dict(), room=f'user_{user_id}') log_to_client(f"截图功能已禁用,跳过截图", user_id, account_id) else: - # 任务非正常完成,重置状态为未开始 + # 任务非正常完成 if account.status not in ["登录失败", "出错"]: account.status = "未开始" socketio.emit('account_update', account.to_dict(), room=f'user_{user_id}') + # 自动重试机制:非登录失败的情况下,自动重试 + elif account.status == "出错" and retry_count < MAX_AUTO_RETRY: + # 延迟5秒后重新加入队列 + log_to_client(f"⚠ 任务执行失败,5秒后自动重试 ({retry_count + 1}/{MAX_AUTO_RETRY})...", user_id, account_id) + account.status = "等待重试" + socketio.emit('account_update', account.to_dict(), room=f'user_{user_id}') + + def delayed_retry(): + time.sleep(5) + if not account.should_stop: + log_to_client(f"🔄 开始第 {retry_count + 1} 次自动重试...", user_id, account_id) + thread = threading.Thread( + target=run_task, + args=(user_id, account_id, browse_type, enable_screenshot, source, retry_count + 1), + daemon=True + ) + thread.start() + active_tasks[account_id] = thread + + threading.Thread(target=delayed_retry, daemon=True).start() finally: # 释放用户级信号量