myxce/docs/left_scheduler_work.md
lei.chen f096be1db5 docs: mark Phase 1 chatbot E2E verified (2026-08-12)
Full Agent chain verified on t1: mcp_operator API key → mcp-server
(scheduler_submit/get_job) → apiserver REST → controller → scheduler →
worker, job submit→run→DONE; cancel(kill)→EXIT. Note the apiserver
controller-restart rejoin gap (DataStore stays stale until apiserver
restart).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-12 08:05:54 +00:00

196 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Scheduler 剩余工作清单(left_scheduler_work)
- 状态:持续更新
- 日期:2026-08-07
- 来源:项目自带 MD 设计文档分析(.kiro/steering、.kiro/specs、docs/、CLAUDE.md)
本文汇总 scheduler 相关的一切剩余/未完成/已知损坏的工作,按优先级排序。每项标注来源文档与状态。
---
## 一、最紧急:当前影响集群的 bug
### 1. bug-1494 — 作业全部 PEND 不调度【已修复,2026-08-11】
- **状态**:已解决(两个子问题均已修复并集群验证)。
- **来源**:`CLAUDE.md`、`docs/Scheduler-Agent-设计文档.md` §10.2b
- **子问题一(已修复,commit 6928f74,bug-1510)**:scheduler 在 worker 未就绪(down/joining)时派发,controller 拒绝(`dispatch_a_job_ worker t1 status=0x10000 ep nil`)并回 `jobDispatchFail` 通知,但 scheduler 的 `sched_handle_notify` 无此 case(丢弃)→ 作业保持 RUN 视图永不重选 → 永久 PEND(worker 恢复也不派发)。**修复**:handler.c 加 `jobDispatchFail` case + `sched_requeue_pend_job()`(重置 PEND + 重新入 fcfs pendJobs)。
- **子问题二(已修复,commit 1a2bd3f)**:controller 重启 / worker 死亡后,scheduler 资源视图 slots=0 → 无法派发。**根因**:worker 死亡时 `mark_worker_unavail` 正确清零 slots=0;worker 重新 join(slots=8)时 controller 推送新 worker,但 scheduler 的 `sched_update_workers` → `sched_add_worker` 用 `key_add` 遇 EEXIST **丢弃新 worker**,scheduler 永久保留旧的 slots=0 → PEND 作业永不派发。**修复**:`sched_update_workers` 对已存在 worker **就地更新**(交换新 resvals/resInUse/status,释放旧对象),并 NULL-guard make_sched_worker。**集群验证**:scheduler 在 worker 死亡时启动(slots=0)→ worker 重新 join(slots=8)→ 之前卡住的 PEND 作业全部派发完成,无 ASAN。
- **关联**:scheduler 运行时重连(component-failover-adoption)仍为独立待办——scheduler 本身不会在 controller 重启后自动重连,需手动重启(但重连后 slots 恢复正常)。
- **临时恢复**:不再需要(worker 重新 join 即可恢复 slots)。
### 2. bug-1490 — apiserver control HTTP 500【已修复,2026-08-07】
- **状态**:已修复
- **来源**:`CLAUDE.md`、`Scheduler-Agent-设计文档.md` §10.2b
- **根因(两个叠加缺陷)**:
1. **array_idx 类型断言 panic → HTTP 500**:`validateJobControl`/`foundJob` 用 `jobinfo.Data["array_idx"].(int64)`,但 `StoreToOrderMaps` 产出的是 `int`(`JobInfo.ArrayIdx` 声明为 `int`)→ panic → Gin Recovery → HTTP 500 → 请求到不了 controller。
2. **jobctrl 联合判别符错误 → -EINVAL**:`backend.ControlJob` 把 `xce_jobctrl_t.action` 设成 `models.JOB_*`(1/2/3/8),但该字段是 capnp `JobControl` union 判别符(`JobControl_u_siginfo=0`/`JobControl_u_ckptoption=1`)→ controller `job_ctrl()` 走错分支(default)→ 每个动作都 -EINVAL。
- **修复**:`normalizeJobInt64`/`jobArrayIdx` 辅助函数 + `jobCtrlDiscriminant` 映射。单测 5 个(controllers 3 + backend 1 + 顺带修了 pre-existing 的 backend cgo 测试编译)。集群 E2E 验证:hold→PSUSP、release→PEND、cancel→EXIT,无 500 无 -EINVAL,全部 daemon 健康。
- **顺带修复**:`resolveExecUser` 被放在 `//go:build cgo` 的 convert.go 里导致 `make test`(CGO_ENABLED=0)下 backend 包编译失败——移到纯 Go 的 convert_pure.go。
### 3. bug-1489 / bug-1491 — 已修复(上下文)
- bug-1491 OrderMap 列格式解析修复(2026-08-01,httpclient.go)
- bug-1489 whitelist 缺 `/xce/v1/apikeys` 修复(2026-08-01,middleware/whitelist.go)
---
## 二、scheduler-controller-msg-gap:已实现但有已知缺陷
spec 声称 36/36 任务完成,但 re-audit(research.md)发现缺陷。来源:`.kiro/specs/scheduler-controller-msg-gap/research.md`。
| 项 | 严重度 | 描述 |
|----|--------|------|
| **G-8** | HIGH | `sched_update_existing_job` 是死代码。notify 驱动的作业更新走 bulk `sched_update_jobs()` 的 CREATE 路径(make_sched_job 新建),损坏/复制作业状态。**很可能与 bug-1494 相关**。Req 3 UB-3.1/3.2 未满足。 |
| **G-3** | MED | 5 个新 op 的 payload(UPDATE_QUEUE/UPDATE_RESOURCES/UPDATE_RESVALS_FULL/UPDATE_RESVALS/JOB_RUSAGE)在 `sched_pend_update_killer` 里 `break;` 从不释放——长驻 daemon 慢速泄漏。 |
| **G-5** | MED | `xce_sched_job_t` 无 rusage 字段。JOB_RUSAGE case 只调插件 hook 就丢 payload。UB-6.1 未满足。 |
| **G-4** | LOW | 即使修好 G-8 让 `sched_update_existing_job` 可达,它也只在作业上应用 state——priority/queue/resreq 未应用。 |
| **G-6** | TODO | 任务 9.2/9.3/9.4/9.6/9.7 勾了 `[x]` 但测试缺失/部分;9.5 测的是本地 stub 非真 schedobj.c。 |
| **G-7** | TODO | 文档漂移:design 说 `xce_sched_op_name` 在 lib/helper,实际是 scheduler.c 里 static `sched_op_name`。 |
| **R-3** | 休眠 | Req 1 处理器前瞻实现,但 controller 当前不推送 Data_data_resources/resvals 表给 scheduler——生产未触发。 |
---
## 三、核心调度引擎重构(scheduler-framework 家族:spec 有、零实现)
来源:`.kiro/specs/scheduler-framework/`、`scheduler-core/`、`scheduler-allocation/`、`scheduler-preemption/`(均只有 requirements/brief,无 design/tasks)。roadmap 显示 "Next: /kiro-spec-requirements scheduler-framework"。
### scheduler-core(Phase 1-3)
| 项 | 描述 |
|----|------|
| 可插拔 picker 接口 | 替代硬编码 `"xce_sched_fcfs"` 字符串,`job_pick_plugin` 字段 + config 加载 + 每 queue 覆盖。核心循环调 `picker->next_job()`。 |
| `builtin_fcfs` 默认实现 | MUST/SHOULD hook 全实现,私有 ordq_t 状态,排序同现状(跨 queue priority desc,队内 priority desc + queue_time asc)。 |
| 无回归保证 | HA soak 必须验证作业挑选顺序零偏差。 |
| core/driver 分离 | 提取 `xce_sched_core_t`,无 mode flag,虚拟时钟 `xce_core_now()`,决策回调。Phase 2。 |
| 模拟模式 | JSONL/.replay 重放 + 虚拟时钟 + snapshot/restore + 确定性重放 + `xceadmin scheduler record` + `--sim/--sim-verify/--interactive`。Phase 3。 |
| 等价保证 | "记录实跑 → 模拟重放 → 决策字节级一致"(AC 7.1)。 |
### scheduler-allocation
| 项 | 描述 |
|----|------|
| 惰性 plan 迭代器 | `xce_alloc_plan_iter_t`:init(resreq)/next()->plan/fini(),cancel-safe。 |
| 惰性 host 迭代器 | `xce_host_iter_t`:init(plan, workers)/next()->worker,复用现有 select 表达式求值器。 |
| parjob 组合分配 | 替换 stub `return 0`:1host×N、2hosts×ceil(N/2)、…、Nhosts×1。 |
| 会话级 resreq 缓存 | keyed on {minTasks,maxTasks,select_node_id,rusage_hash,user,queue,project},作业 ingest 时预计算。 |
| seqjob 重包 | 1host/1slot 走同一迭代器接口,验证抽象。 |
### scheduler-preemption
| 项 | 描述 |
|----|------|
| `XCE_DECISION_PREEMPT` | decision.h 新 opcode + `xce_preempt_decision_t`(victim_jobids, SIGSTP, preempting_jobid)。 |
| victim 选择策略 | 默认 `"lowest_priority_first"`,LSF 式跨 queue(preemptible_queues),最小足够 victim 集,安全护栏(不抢占同/高优先级、非抢占 queue)。 |
| SIGSTP 管线 | scheduler→controller→worker→SIGSTP 进程组,作业→JOB_SUSPENDED,复用 HOOK_DETAIL_JOB_STOP。每 queue `preemptible/preempt_policy/preemptible_queues` 字段。 |
| 核心循环集成 | 分配失败后、pending 前:can_preempt → 选 victim → 发 PREEMPT → preempting 作业下一轮再派(异步抢占)。 |
| 后续推迟项 | SIGKILL+requeue 升级、JOB_SUSPENDED resume 机制。 |
---
## 四、故障转移 / 重连
### component-failover-adoption(14 任务全未勾选)
- **来源**:`.kiro/specs/component-failover-adoption/`
- **关键结论**:requirements.md Background 明确 "**scheduler 没有任何运行时重连/rejoin 逻辑**——连的 controller 死后,scheduler 无法切换到其他候选"。
- 任务 3.1:把 scheduler 的 per-candidate 循环换成单一 library 驱动的 connect/join + rejoin 回调。
- 任务 3.2:scheduler 多 controller join E2E 测试。
- Req 3:重连重试/backoff 不能阻塞 picker 线程(保持现有线程拆分)。
- Req 5:per-candidate 重连诊断日志(成功/不可达/standby 重定向)。
### P2.5
- **来源**:`product.md:35`、`docs/superpowers/plans/2026-05-07-p25-discovery.md`
- product.md 标 P2.5 "In progress";P2.5-6 描述 scheduler `--peers`/`--ca-cert` CLI 更新;P2.5-7(CGo bridge)推迟。是否全完成文档不确定。
- **注意**:P2.5 与 component-failover-adoption 用了两套技术路径(xce_connect_cluster 裸 endpoint vs xcecli_ctx_t/XCECLI_FAILOVER_CALL),文档未调和。
---
## 五、scheduler agent / MCP server(Phase 2-4)
来源:`docs/Scheduler-Agent-设计文档.md`
| 项 | 状态 | 描述 |
|----|------|------|
| Phase 2:SSE 事件流 | 计划 | apiserver SSE endpoint + EventBroker,schedulerclient `WatchJobs()`,mcp-server 接入。ADR-004 设计完成待实施。估 2-3 天。 |
| Phase 3:LSF adapter | 计划 | CLI 解析优先,Python Sidecar 后续。估 +1 月。 |
| Phase 4:Slurm + K8s | 计划 | slurmrestd + CLI fallback;client-go。估 +1 月。 |
| modify 工具 | 推迟 | apiserver 当前无 modify 端点(control 仅 kill/stop/resume/checkpoint),需新增后端端点。 |
| 未决决策 | 未解决 | LLM 模型选型(Claude API/自建/混合);多集群 URM 源识别;air-gapped LLM 访问。 |
---
## 六、roadmap / 加固项
| 项 | 状态 | 描述 |
|----|------|------|
| 调度决策过 commit barrier | 计划 | DISPATCH/PEND/PREEMPT 需过 majority commit barrier。多文档提及为独立加固项,从 scheduler-framework scope 推迟。 |
| worker-rejoin-resync | backlog | worker 重连重报运行/完成作业状态(bug-396 兜底)。依赖 ha-consistency-invariants。scheduler 间接受影响(恢复作业需调度状态核对)。 |
| entity-bearing snapshots | backlog | 解锁 config-upgrade-snapshot、基于快照的状态传输。影响 scheduler 模拟(snapshot/restore)。COW 机制存在但休眠。 |
| project-resource-ownership | 未来 spec | 层级项目树 + 资源配额,project-aware picker 插件,queue↔project 映射。核心循环零改动(只加新 picker)。 |
| perf-tuning-extraction / clusterconfig-schema-split | 计划 | 配置 schema 变更触及 scheduler 配置摄取。 |
| bulk job-array query/cancel | 推迟 | 依赖 job-array-single-wal-record。 |
---
## 七、文档空白(设计层面没人写过)
1. **调度决策 commit barrier 细节**——roadmap 只提了标题,无 spec/design。
2. **scheduler 状态在 controller failover 后如何同步**——全量重推?增量?文档沉默。roadmap:67 提到 lightweight rejoin re-attach(当前是 full-state rejoin,"大但罕见")。
3. **scheduler 模拟模式 vs controller WAL replay 关系**——failover 后 scheduler 从 controller WAL 重放还是收新状态推送?未讨论。
4. **core/driver 分离下的对象内存/生命周期**——三线程(picker/allocator/driver)async 生产者/消费者模型下借用指针的归属未细化。
5. **无 scheduler 专属 HA soak 测试**——多次提到 "HA soak regression" 但无 `/xce-test-ha` 变体专门跑 scheduler failover/reconnect。
6. **`src/scheduler/CLAUDE.md` 太薄**——约 25 行,无 spec 状态、无已知 bug 清单、无剩余工作节。建议补全(对照 `src/controller/CLAUDE.md`)。
7. **scheduler 与 raft/TLA+ 架构整合**——raft 系列落地后 scheduler 与 log/commit 模型的交互未讨论。
---
## 八、scheduler-agent(chatbot / AI 辅助)剩余工作
- 状态:持续更新
- 日期:2026-08-07
- 来源:`docs/Scheduler-Agent-设计文档.md`(v1.2,权威设计文档)、`src/docs/chatbot-verification.md`、`src/frontend/CLAUDE.md`、`CLAUDE.md`
- **注意**:feature 直接从设计文档实现,**未走 .kiro spec 流程**(`.kiro/specs/` 无 scheduler-agent/chatbot spec)。`/home/lchen/code/chatbot/` 是 XCE 完整镜像工作树,代码两份一致。
### 架构与现状
用户自然语言 → Claude Code(LLM)→ MCP stdio → mcp-server → schedulerclient → apiserver REST → controller(C 后端)。**不是独立聊天组件,而是自然语言调度管理 Agent 框架**。
**已完成**:
| Phase | 内容 | 状态 |
|-------|------|------|
| Phase 0 | 只读 MCP Server:6 读工具、schedulerclient、`mcp_readonly` 角色、API Key 认证 | ✅ 2026-07-26 |
| Phase 1 | 4 写工具(submit/cancel/hold/release)、`general_serial` 模板、`mcp_operator`、`dry_run` 审查 | ✅ 2026-08-01(代码);**2026-08-12 完整集群 E2E 验证通过**:submit→运行→DONE、cancel(kill)→EXIT、读接口全通。注意:job control 动作是 kill/stop/resume/checkpoint(schedulerclient 已正确映射) |
**注意**:apiserver 在 controller 重启后**不会自动重新 join**(只重连 TCP,DataStore 保持陈旧为空)——controller 重启后需手动重启 apiserver 才会重新收到作业推送。这与 scheduler/worker 的重连缺口同类,属 component-failover-adoption 待办。
代码:`src/frontend/mcp-server/`(10 工具,~1300 行)、`src/frontend/schedulerclient/`(45 测试)、apiserver API Key + RBAC 支持。
### 1. 阻塞性 bug(影响 chatbot E2E 验证)
| Bug | 影响 |
|-----|------|
| **bug-1490** | ✅ 已修复(c90e63e)。MCP 写工具(submit/hold/release/cancel)集群 E2E 验证通过;`scheduler_get_job` 的 CompConditions 过滤 bug 也已修复(0572740)。另修了部署缺口:/opt/xce/config 缺 rbac.yaml 导致 mcp API key 全 403 |
| **bug-1494** | 作业全 PEND 不调度,Agent 提交流程无法完成。**已修复(2026-08-11)**:子问题一 dispatch-fail 重试(bug-1510)+ 子问题二 worker 重新 join 后 slots 不更新(见第一节) |
| **chatbot 过度建议** | ✅ 已缓解(3db216c):mcp-server 加 server instructions + 状态工具 report-only 描述,防止 LLM 把非 OK 状态当事故、主动给一堆排查建议 |
### 2. Phase 2:监控 + 纠错闭环(未开始,估 2-3 天)
- **SSE 事件流**(ADR-004 设计已完、未实现):apiserver SSE endpoint + EventBroker,schedulerclient `WatchJobs()`,mcp-server 事件接入。Agent 工作流:submit → watch → analyze → auto-handle
- 3 个高级工具:`scheduler_analyze_failure`、`scheduler_suggest_resources`、`scheduler_estimate_wait_time`
### 3. Phase 3 / Phase 4:后端适配器(未开始)
- Phase 3:**LSF adapter**(CLI 解析优先,Python Sidecar 后续,估 +1 月)
- Phase 4:**Slurm**(slurmrestd)+ **K8s**(client-go)(估 +1 月)
### 4. 推迟 / 未决
- `scheduler_modify` 工具推迟——apiserver 当前无 modify 端点(control 仅 kill/stop/resume/checkpoint),需新增后端端点
- 3 个未决决策:LLM 模型选型(Claude API/自建/混合)、多集群 URM 来源识别、air-gapped LLM 访问
### 5. 设计层加固(文档已写、代码零实现)
- **Auto-pilot 模式**:用户显式授权范围内的自主行为
- **AI 操作审计日志**:每条操作记 `[timestamp] [user] [action] [params] [confirmed?]`
- **Golden test suite**:同一自然语言输入 → 同一工具调用序列的回归测试
---
## 建议优先级
1. **bug-1490**(apiserver control HTTP 500)——阻塞 chatbot 写工具 E2E,小而明确,能立即修。
2. **bug-1494**(作业 PEND)——根因已定位(worker+scheduler 不自愈)。G-8 死代码(scheduler 作业更新路径损坏)很可能是元凶。
3. **msg-gap G-8/G-3/G-5**——小而明确,能立即修。
4. **component-failover-adoption**(scheduler 重连)——与 bug-1494 的 join 链路疑点直接相关。
5. scheduler-agent Phase 2(SSE 事件流)——依赖 bug-1490/bug-1494 先修好。
6. scheduler-framework 重构——大规划,建议等前 5 项稳定后再动。