mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 05:11:59 +00:00
45fe01effe
- 只比成功结束的运行,基准也只取成功的:失败、取消的运行指标不全,和上一次比只会得出「移除 N 个」,拿失败的那次当 基准每个指标都成了「新增」。基准改成自己查同一定时任务、同一工作流、比这次先发起的运行里成功并封存的最近一次, 不再用对比接口的 default_base(按结束时间挑:老的失败运行事后被接着跑完,会拿后一次触发当它的「上一次」)。 中间隔着失败、取消的运行时,通知写「与上一次成功的运行(#短编号,日期)相比」,Fire.compare 多一个 previous - 和封存绑定:运行的封存要盖住最后一条结束事件才算封存完(sealed_now)。runner 先写终态、再另起会话封存,失败后 接着跑完的运行在两步之间还带着失败时的清单哈希,以前这一拍会直接认领、按旧封存比、通知里写旧的清单哈希;现在 等新的封存,等不来就照常推送但不比、不写哈希。停在审批上的通知也不再写失败时留下的哈希。对比工件连同两边的清单 哈希一起存,触发历史发现任何一边不在终态或清单哈希变了就给 null;对比途中封存变了不记(条件写) - 时机和时限:锁里只挑出状态有变化的触发,认领挪到对比之后、锁外按条件 UPDATE 做。对比最多等 20 秒(含排队), 同一时刻最多 2 个;超时只记警告,通知不带对比照常推送。停机时扫描在对比途中被取消,这次触发还没认领,下次照常 比、照常推(以前先认领、后比,这条通知会永远丢掉)。同一份封存已经比过的直接用记下的结果 - 失败通知:从没开始执行的,原因刚写过,处理行不再让人「查看原因」,任务在排期上写「下一次触发会照常发起」,停用 的写怎么重新发起;开始执行过的改成「请在 AgentLab 的「记录」中查看失败原因」,和挂起那句指向同一个导航入口 - 新增 test_scheduler_compare_guards.py(封存绑定、时限、取消、并发、复用),test_scheduler_compare.py 补真实缺 指标的失败运行、上一次失败、补跑老运行几种用例;去掉实现逐项验证过会变红
52 lines
2.2 KiB
Python
52 lines
2.2 KiB
Python
"""定时任务的后台调度:到点按定时任务的设置发起工作流运行,结束、失败、停在审批时推送 Webhook。
|
|
|
|
- cron.py:五字段 cron 的解析、下次触发、中文描述
|
|
- service.py:输入模板、和工作流入口字段的对照、发起一次触发(调度循环和「立即运行」共用)
|
|
- loop.py:调度循环,条件 UPDATE 认领到点的任务
|
|
- webhook.py:通知推送(通用 / 飞书 / 企业微信 / 钉钉)
|
|
- auto_compare.py:运行成功结束后和同一定时任务上一次成功的运行自动对比,结果记在触发记录上,通知里只带计数摘要和
|
|
对比页链接
|
|
|
|
服务启动时(main.py 的 lifespan)只在 scheduler_enabled() 时调 start,关闭时总是调 stop——stop 要能在没 start
|
|
过时安全返回。start 自己也看一次开关:拷来的数据目录(检查脚本的 --stacks、验收副本)不管从哪条路径起服务,
|
|
都不会替原库把定时任务再执行一遍。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from app.core.config import Settings, settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def scheduler_enabled(config: Settings | None = None) -> bool:
|
|
"""调度循环开不开:AGENTLAB_SCHEDULER,默认开,0 / false / off 关(见 core/config.py)。
|
|
|
|
config 只给测试用:settings 是模块级单例,改环境变量不会让它重读。"""
|
|
return bool((config or settings).scheduler)
|
|
|
|
|
|
async def start(*, interval: float | None = None, config: Settings | None = None) -> bool:
|
|
"""起调度循环,返回起没起。开关关着时什么都不做;已经在跑时不起第二个。interval 只给测试用。"""
|
|
if not scheduler_enabled(config):
|
|
logger.info("定时任务调度已关闭(AGENTLAB_SCHEDULER),不会自动发起运行")
|
|
return False
|
|
from app.scheduler.loop import TICK_SECONDS, runner
|
|
|
|
await runner.start(interval if interval is not None else TICK_SECONDS)
|
|
return True
|
|
|
|
|
|
async def stop() -> None:
|
|
"""停调度循环,等手上的那一轮收尾。没 start 过也能安全调用。"""
|
|
from app.scheduler.loop import runner
|
|
|
|
await runner.stop()
|
|
|
|
|
|
def running() -> bool:
|
|
from app.scheduler.loop import runner
|
|
|
|
return runner.running()
|