106 lines
3.6 KiB
Python
106 lines
3.6 KiB
Python
import asyncio
|
|
import sys
|
|
from datetime import datetime, timedelta
|
|
|
|
from loguru import logger
|
|
|
|
from core.config import Config
|
|
from core.database import DatabaseManager
|
|
from core.logger import setup_logger
|
|
|
|
|
|
class RetryingAccountsReset:
|
|
def __init__(self):
|
|
self.config = Config.from_yaml()
|
|
self.logger = setup_logger(self.config)
|
|
self.db_manager = DatabaseManager(self.config)
|
|
|
|
async def initialize(self):
|
|
"""初始化数据库"""
|
|
await self.db_manager.initialize()
|
|
|
|
async def cleanup(self):
|
|
"""清理资源"""
|
|
await self.db_manager.cleanup()
|
|
|
|
async def reset_stuck_accounts(self, timeout_minutes=30):
|
|
"""重置卡在retrying状态的账号"""
|
|
try:
|
|
# 计算超时时间
|
|
timeout_time = datetime.now() - timedelta(minutes=timeout_minutes)
|
|
timeout_str = timeout_time.strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
self.logger.info(f"开始重置超时的retrying账号 (超过{timeout_minutes}分钟)")
|
|
|
|
async with self.db_manager.get_connection() as conn:
|
|
# 查询当前处于retrying状态的账号数量
|
|
cursor = await conn.execute(
|
|
"SELECT COUNT(*) FROM email_accounts WHERE status = 'retrying'"
|
|
)
|
|
count = (await cursor.fetchone())[0]
|
|
|
|
if count == 0:
|
|
self.logger.info("没有找到处于retrying状态的账号")
|
|
return 0
|
|
|
|
# 更新超时的retrying账号为failed状态
|
|
cursor = await conn.execute(
|
|
"""
|
|
UPDATE email_accounts
|
|
SET
|
|
status = 'failed',
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE
|
|
status = 'retrying'
|
|
AND updated_at < ?
|
|
RETURNING id, email
|
|
""",
|
|
(timeout_str,)
|
|
)
|
|
|
|
# 获取被重置的账号信息
|
|
reset_accounts = await cursor.fetchall()
|
|
await conn.commit()
|
|
|
|
reset_count = len(reset_accounts)
|
|
|
|
# 打印重置的账号列表
|
|
if reset_count > 0:
|
|
self.logger.info(f"已重置 {reset_count} 个账号状态从retrying到failed:")
|
|
for account in reset_accounts:
|
|
self.logger.debug(f"ID: {account[0]}, 邮箱: {account[1]}")
|
|
else:
|
|
self.logger.info(f"没有找到超过{timeout_minutes}分钟的retrying账号")
|
|
|
|
return reset_count
|
|
|
|
except Exception as e:
|
|
self.logger.error(f"重置retrying账号失败: {str(e)}")
|
|
return 0
|
|
|
|
|
|
async def main():
|
|
# 解析命令行参数
|
|
timeout_minutes = 30 # 默认超时时间30分钟
|
|
if len(sys.argv) > 1:
|
|
try:
|
|
timeout_minutes = int(sys.argv[1])
|
|
except ValueError:
|
|
print(f"参数错误: 超时时间必须是整数,将使用默认值 {timeout_minutes}分钟")
|
|
|
|
# 初始化
|
|
reset = RetryingAccountsReset()
|
|
await reset.initialize()
|
|
|
|
try:
|
|
# 执行重置
|
|
await reset.reset_stuck_accounts(timeout_minutes)
|
|
|
|
except Exception as e:
|
|
logger.error(f"程序执行出错: {str(e)}")
|
|
finally:
|
|
await reset.cleanup()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main()) |