fix(schedules): refresh untouched builtin config so checks get new capabilities
Built-in agent checks kept the config stored at first registration, so check.pending never received decision.list / subscription.list added in AG-3 and the patrol could not read pending items (REAL-2 scenario g). Track config_customized (migration 0045); sync replaces config with the code default unless the user PATCHed it. Needs image rebuild. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
96fc089f92
commit
bd0e011748
6 files changed
+52
-5
No files matched your search
@@ -94,7 +94,8 @@ export function runView(r: ScheduledJobRunRow): ScheduledJobRun {
|
||||
|
||||
/**
|
||||
* 把代码登记的定义同步进表:新行按默认值插入;已有行刷新名称/分组/默认值,
|
||||
* 用户改过(customized)的 enabled/schedule 保留;config 以表内值为准、补上新增的默认键。
|
||||
* 用户改过(customized)的 enabled/schedule 保留;config 用户改过(config_customized)时以表内值为准、补上新增的默认键,
|
||||
* 否则整体换成代码默认值(新增的巡检白名单能力等才能进旧行)。
|
||||
* 未改过且默认调度变了的行,下次运行改为立即(随后按新周期)。
|
||||
* 同步时代码里已不再登记的内置 task 行标为不可用(不会执行,看板显示"未登记")。
|
||||
*/
|
||||
@@ -121,7 +122,8 @@ export async function syncDefinitions(db: Kysely<DB>, defs: readonly ScheduledJo
|
||||
default_schedule = excluded.default_schedule,
|
||||
enabled = case when scheduled_job.customized then scheduled_job.enabled else excluded.enabled end,
|
||||
schedule = case when scheduled_job.customized then scheduled_job.schedule else excluded.schedule end,
|
||||
config = excluded.config || scheduled_job.config,
|
||||
config = case when scheduled_job.config_customized then excluded.config || scheduled_job.config
|
||||
else excluded.config end,
|
||||
next_run_at = case
|
||||
when not scheduled_job.customized and scheduled_job.schedule is distinct from excluded.schedule then ${now}
|
||||
else coalesce(scheduled_job.next_run_at, excluded.next_run_at) end`.execute(db);
|
||||
@@ -221,6 +223,7 @@ export async function updateJob(
|
||||
} else {
|
||||
set.config = JSON.stringify({ ...((row.config ?? {}) as object), ...patch.config });
|
||||
}
|
||||
set.config_customized = true;
|
||||
}
|
||||
return await db.updateTable("scheduled_job").set(set).where("id", "=", id).returningAll().executeTakeFirstOrThrow();
|
||||
}
|
||||
|
||||
@@ -144,6 +144,22 @@ describe.skipIf(!hasPg)("定时任务注册表(真实 PG)", () => {
|
||||
expect(new Date(cron.body.data.nextRunAt).getHours()).toBe(4);
|
||||
});
|
||||
|
||||
it("config:没改过的行随代码默认值整体更新;PATCH 过的保留表内值", async () => {
|
||||
const def = (config: Record<string, unknown>) =>
|
||||
counting("test.cfg", {
|
||||
defaults: { name: "c", group: "download", schedule: { type: "interval", everyMs: 60_000 }, config },
|
||||
});
|
||||
registerScheduledJob(ctx, def({ list: ["a"] }));
|
||||
await sched.tick();
|
||||
registerScheduledJob(ctx, def({ list: ["a", "b"] }));
|
||||
await sched.tick();
|
||||
expect((await job("test.cfg")).config).toEqual({ list: ["a", "b"] });
|
||||
expect((await api("PATCH", "/schedules/test.cfg", { config: { list: ["x"] } })).status).toBe(200);
|
||||
registerScheduledJob(ctx, def({ list: ["a", "b", "c"], extra: 1 }));
|
||||
await sched.tick();
|
||||
expect((await job("test.cfg")).config).toEqual({ list: ["x"], extra: 1 });
|
||||
});
|
||||
|
||||
it("立即执行幂等(合并重复请求)且不改下次运行时间", async () => {
|
||||
registerScheduledJob(
|
||||
ctx,
|
||||
|
||||
Reference in new issue
Block a user