feat(worker): IO Worker 分道(WK-1)
io worker 进程内按任务声明的 lane 分文件 / 网络 / 维护三条道,各自并发(缺省 2/4/1)、 各自排队;维护道在文件道或网络道有排队/运行时让路(连续 10 分钟放行一个),调度器内联的 清理/回填/保留期裁剪也走维护道。并发在 设置 → 自动化 → 高级 热生效,env 覆盖;旧 WORKER_CONCURRENCY 映射到网络道。运行状态页按道显示运行中/并发/排队。归属表写进 docs/runbook/dev.md,ci 与注册表逐项核对。 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
68f53390f6
commit
da33cad81d
38 files changed
+1240
-105
No files matched your search
@@ -48,6 +48,12 @@ export interface ScheduledJobDef {
|
||||
/** 稳定 key(表主键),如 feeds.poll */
|
||||
key: string;
|
||||
kind?: ScheduleKind;
|
||||
/**
|
||||
* 执行道(WK-1):"maintenance" = 在调度器里内联干重活的维护任务(清理、回填、保留期裁剪),
|
||||
* 与 io worker 的维护道共用并发、文件道 / 网络道有活时让路(立即执行不让路)。
|
||||
* 省略 = 轻量调度(只入队任务或很快结束),任务本身按它的 lane 执行。
|
||||
*/
|
||||
lane?: "maintenance";
|
||||
defaults: ScheduledJobDefaults;
|
||||
run: JobRunFn;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { SCHEDULE_CHANGED_EVENT } from "@umt/contracts";
|
||||
import { type DB, type Kysely, type ScheduledJobRow, sql } from "@umt/db";
|
||||
import type { Logger } from "pino";
|
||||
import type { EventBusPort } from "../../http/sse.ts";
|
||||
import { laneControllerOf } from "../../worker/lanes.ts";
|
||||
import type { ServerContext } from "../types.ts";
|
||||
import { runAgentCheck } from "./agent-checks.ts";
|
||||
import type { JobRunFn, JobRunResult, ScheduleRegistry } from "./registry.ts";
|
||||
@@ -158,10 +159,20 @@ export class Scheduler {
|
||||
.limit(50)
|
||||
.execute();
|
||||
const started: string[] = [];
|
||||
const lanes = laneControllerOf(this.ctx);
|
||||
for (const job of due) {
|
||||
const fn = this.runFor(job);
|
||||
if (!fn) continue;
|
||||
const p = this.execute(job, fn).finally(() => this.inflight.delete(job.id));
|
||||
// 内联维护任务进维护道:占不到并发或正在让路就留到下一轮(不改 next_run_at);立即执行不让路
|
||||
let release: (() => void) | null = null;
|
||||
if (lanes && this.registry.get(job.id)?.lane === "maintenance") {
|
||||
release = await lanes.enterMaintenance(job.run_requested_at !== null);
|
||||
if (!release) continue;
|
||||
}
|
||||
const p = this.execute(job, fn).finally(() => {
|
||||
release?.();
|
||||
this.inflight.delete(job.id);
|
||||
});
|
||||
this.inflight.set(job.id, p);
|
||||
started.push(job.id);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user