mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 03:51:58 +00:00
a2a19df9df
- 表:schedules(Webhook 地址和签名密钥加密存放、next_run_at 存 UTC、version 乐观锁)、schedule_fires((任务,
fire_at, kind) 唯一)、webhook_deliveries;新表由 create_all 建,不用迁移
- 输入模板:{{ schedule.yesterday }} 这类变量按计划触发时间在任务时区算(不按「现在」:补发晚了、零点前后立即
运行,「昨天」都是那次触发的昨天),上一次计划触发时间按 cron 往前找,同一次触发永远渲染出同一份输入;未知
变量、未知过滤器、{{ }} 不成对都拦下,声明了入口字段的工作流还对照字段名和必填项
- 调度循环:每 15 秒一拍,条件 UPDATE 认领到点的任务并推进到下一次,两拍并发只有一拍认领得到,触发记录的唯一
约束是第二道保险;上一次运行没结束(含停在审批、服务重启挂起的)记跳过;错过的只看最近一次,在宽限内补一次、
超出记跳过,积压不补;发起走 launch_run,拒绝的原话记成未能发起,别的异常记通用说明、详情进日志;stop 等手上
这一拍收尾,开关关着时 start 不起循环
- Webhook:通用 JSON(可选 HMAC 签名头)、飞书文本、企业微信 markdown、钉钉 markdown,按各平台算法签名;运行
结束、失败、确有待审批时按订阅推一次,结束的等封存好再推,没订阅、没配 Webhook 的也记下已处理,之后配上不会
补推旧的;10 秒超时、失败重试 3 次(4xx 不重试),每次推送记一条记录;通知里没有报告数字和原始报错,日志和
错误里只有主机名(httpx 自己的请求日志也换成主机名)
- 设置 notify.public_base_url:通知里的运行链接 = 它 + /runs/{id},只收 http(s) 地址,末尾的 / 去掉
45 lines
1.6 KiB
Python
45 lines
1.6 KiB
Python
"""AGENTLAB_SCHEDULER:定时任务的调度循环开不开。
|
|
|
|
默认开;0 / false / off 关。检查脚本的 --stacks 拷一份数据目录另起服务时靠它关掉,
|
|
否则拷贝里的定时任务会替原库再发起一遍运行、再发一遍 webhook。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from app import scheduler
|
|
from app.core.config import Settings
|
|
|
|
|
|
def flag(monkeypatch, value: str | None) -> bool:
|
|
if value is None:
|
|
monkeypatch.delenv("AGENTLAB_SCHEDULER", raising=False)
|
|
else:
|
|
monkeypatch.setenv("AGENTLAB_SCHEDULER", value)
|
|
# 不读仓库里的 .env:测的是环境变量本身的解析
|
|
return scheduler.scheduler_enabled(Settings(_env_file=None))
|
|
|
|
|
|
@pytest.mark.parametrize("value", [None, "", " ", "1", "true", "on", "TRUE", "yes"])
|
|
def test_enabled_by_default_and_when_switched_on(monkeypatch, value):
|
|
assert flag(monkeypatch, value) is True
|
|
|
|
|
|
@pytest.mark.parametrize("value", ["0", "false", "off", "False", "OFF", "no"])
|
|
def test_switched_off(monkeypatch, value):
|
|
assert flag(monkeypatch, value) is False
|
|
|
|
|
|
def test_unrecognized_value_fails_at_startup(monkeypatch):
|
|
"""认不出的写法不猜开还是关:启动时就报错"""
|
|
with pytest.raises(ValidationError):
|
|
flag(monkeypatch, "maybe")
|
|
|
|
|
|
async def test_start_and_stop_are_safe_noops():
|
|
"""测试环境关着调度(conftest):start 不起循环,没 start 过直接 stop 也不出错。开着时的循环见 test_scheduler_loop"""
|
|
await scheduler.stop()
|
|
await scheduler.start()
|
|
await scheduler.stop()
|