mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-11 15:00:00 +08:00
♻️ refactor(scheduler): 重构定时任务服务架构并增强用户体验 (#1967)
**架构重构** - 拆分为 Service、Repository、Adapter 三层架构,提升模块化 - 统一 APScheduler Job ID 生成方式,优化 ScheduleTargeter 逻辑 **新增功能** - 支持定时任务时区配置 - 新增"运行中"任务状态显示 - 为"所有群组"任务增加随机延迟,分散并发压力 **用户体验优化** - 重构操作反馈消息,提供详细的成功提示卡片 - 优化任务查看命令的筛选逻辑 - 统一删除、暂停、恢复、执行、更新操作的响应格式 Co-authored-by: webjoin111 <455457521@qq.com>
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
"""
|
||||
引擎适配层 (Adapter)
|
||||
|
||||
封装所有对具体调度器引擎 (APScheduler) 的操作,
|
||||
使上层服务与调度器实现解耦。
|
||||
"""
|
||||
|
||||
from nonebot_plugin_apscheduler import scheduler
|
||||
|
||||
from zhenxun.models.schedule_info import ScheduleInfo
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
from .job import _execute_job
|
||||
|
||||
JOB_PREFIX = "zhenxun_schedule_"
|
||||
|
||||
|
||||
class APSchedulerAdapter:
|
||||
"""封装对 APScheduler 的操作"""
|
||||
|
||||
@staticmethod
|
||||
def _get_job_id(schedule_id: int) -> str:
|
||||
"""生成 APScheduler 的 Job ID"""
|
||||
return f"{JOB_PREFIX}{schedule_id}"
|
||||
|
||||
@staticmethod
|
||||
def add_or_reschedule_job(schedule: ScheduleInfo):
|
||||
"""根据 ScheduleInfo 添加或重新调度一个 APScheduler 任务"""
|
||||
job_id = APSchedulerAdapter._get_job_id(schedule.id)
|
||||
|
||||
if not isinstance(schedule.trigger_config, dict):
|
||||
logger.error(
|
||||
f"任务 {schedule.id} 的 trigger_config 不是字典类型: "
|
||||
f"{type(schedule.trigger_config)}"
|
||||
)
|
||||
return
|
||||
|
||||
job = scheduler.get_job(job_id)
|
||||
if job:
|
||||
scheduler.reschedule_job(
|
||||
job_id, trigger=schedule.trigger_type, **schedule.trigger_config
|
||||
)
|
||||
logger.debug(f"已更新APScheduler任务: {job_id}")
|
||||
else:
|
||||
scheduler.add_job(
|
||||
_execute_job,
|
||||
trigger=schedule.trigger_type,
|
||||
id=job_id,
|
||||
misfire_grace_time=300,
|
||||
args=[schedule.id],
|
||||
**schedule.trigger_config,
|
||||
)
|
||||
logger.debug(f"已添加新的APScheduler任务: {job_id}")
|
||||
|
||||
@staticmethod
|
||||
def remove_job(schedule_id: int):
|
||||
"""移除一个 APScheduler 任务"""
|
||||
job_id = APSchedulerAdapter._get_job_id(schedule_id)
|
||||
try:
|
||||
scheduler.remove_job(job_id)
|
||||
logger.debug(f"已从APScheduler中移除任务: {job_id}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def pause_job(schedule_id: int):
|
||||
"""暂停一个 APScheduler 任务"""
|
||||
job_id = APSchedulerAdapter._get_job_id(schedule_id)
|
||||
try:
|
||||
scheduler.pause_job(job_id)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def resume_job(schedule_id: int):
|
||||
"""恢复一个 APScheduler 任务"""
|
||||
job_id = APSchedulerAdapter._get_job_id(schedule_id)
|
||||
try:
|
||||
scheduler.resume_job(job_id)
|
||||
except Exception:
|
||||
import asyncio
|
||||
|
||||
from .repository import ScheduleRepository
|
||||
|
||||
async def _re_add_job():
|
||||
schedule = await ScheduleRepository.get_by_id(schedule_id)
|
||||
if schedule:
|
||||
APSchedulerAdapter.add_or_reschedule_job(schedule)
|
||||
|
||||
asyncio.create_task(_re_add_job()) # noqa: RUF006
|
||||
|
||||
@staticmethod
|
||||
def get_job_status(schedule_id: int) -> dict:
|
||||
"""获取 APScheduler Job 的状态"""
|
||||
job_id = APSchedulerAdapter._get_job_id(schedule_id)
|
||||
job = scheduler.get_job(job_id)
|
||||
return {
|
||||
"next_run_time": job.next_run_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
if job and job.next_run_time
|
||||
else "N/A",
|
||||
"is_paused_in_scheduler": not bool(job.next_run_time) if job else "N/A",
|
||||
}
|
||||
Reference in New Issue
Block a user