将 TLUSTY/SYNSPEC 拆为各自独立的 enabled/policy/strategies 阶段,
以策略链自动弹栈取代单级 seed_step 布尔回退;定向修复 2026-08-02
僵尸任务涡旋事故;新增节点并发配额热调;前端详情页从 1412 行巨型
视图拆为薄控制器 + detail 子模块,并补齐工具层与单测。
引擎与调度(task_engine_decoupling_design.md)
- models.rs: 新增 StagePolicy / EngineStageConfig / TaskSpec 阶段字段、
normalize_compat() 校正旧版在途消息策略链、failed_stage 归因
- scheduler.rs: resolve_dispatchable_chain 派发门控、
trigger_strategy_fallback 按 failed_stage 精确弹栈;启动期
force_recompute/skip_converged(默认)/skip_failed 三策略
- db.rs: tasks 表 +7 列持久化阶段配置;终态守卫
(mark_grid_point_running 仅 pending/queued→running;
record_task_report 拒绝迟到失败翻黑 converged);策略弹栈快照
僵尸涡旋修复(runbook-20260802-zombie-vortex-fix.md)
- 全链路跨库活性交叉校验:派发/claim/孤儿回收/回退统一查 MQ 队列活性,
活则放行、死则清僵尸,结构性消除"每点重复派发"
- stop/重启卫生:清队列同步 delete_tasks_by_ids,杜绝遗留 pending 行
- report_task: 幂等吸收 + 409 区分迟到冗余结果,仅 state_changed 时回退
- MQ: NULL workflow_name 回填 __legacy__、requeue 后迟到上报被 403 竞态修复
动态 CPU 配额(dynamic_cpu_slots_design.md)
- admin.rs: POST /admin/nodes/:id/quota(Option<Option<i32>> 区分
缺字段/显式 null);nodes 表 +admin_max_slots
- worker.rs: effective_max_slots = min(admin, physical),心跳下发原子生效
科学产物保全(tlusty_result_artifacts.md)
- runner.rs: SYNSPEC 启动前快照 fort.12/fort.14 → .bfac/.emflux 防覆盖
- 半失败点(大气收敛+光谱失败)改判 Failed 并写入 note;仅 SYNSPEC
场景不再恒判失败;撤销归档 LRU 200 上限改为永久保留
- executor.rs: 透传 synspec_params 数值参数(此前固定 None)
前端(dashboard/)
- workflowDetail.js 1412→328 行,拆出 views/detail/{ctx,overview,
pointsTable,parSets,pointPanel}.js,AbortController 治理监听/请求生命周期
- 删除 wfActions.js,新增 wfEnginePanel.js(双阶段三维配置编辑面板)
- 新增 utils/{errors,format,icons,polling,yamlStage}.js 纯函数模块
- 路由级动态 import 代码分割;节点配额三点菜单 + Modal 管理
- 首次引入 node:test 单测(format/polling/yamlStage/psCache,644 行)
- 系统性补齐 a11y:skip-link、ARIA、Tab 键盘漫游、toast 关闭、退出动画
文档与工具
- 新增 6 篇设计/调研:引擎解耦、动态配额、涡旋 runbook、
光谱正确性分析、收敛判断、产物归档
- PIPELINE/design/api/database 等协同重写为分布式 C/S 架构口径
- scripts/fetch_results.sh 跨节点产物备份;import_results 按 cno 升序导入
- workflows/sdB_cno.yaml: 新增 tlusty/synspec_stage 配置块,修正 wstart 笔误
222 lines
14 KiB
Markdown
222 lines
14 KiB
Markdown
# DCTS 任务计算引擎解耦与阶段独立配置架构设计方案
|
||
|
||
## 1. 背景与现状分析 (Background & Current Bottlenecks)
|
||
|
||
### 1.1 现状与概念降维问题
|
||
|
||
在 DCTS 早期版本中,任务类型通过单级平铺枚举 `TaskType`(如 `ColdRun`, `SeedStep`)定义。它将 TLUSTY 阶段的“初始猜想策略”、SYNSPEC 阶段的执行与否,以及全局任务的生命周期强行绑定在一起,导致概念降维与严重耦合。
|
||
|
||
### 1.2 组合爆炸风险
|
||
|
||
随着扩展能力(如 `Interpolation`, `LineListScan`)的加入,平铺枚举会导致 $N \times M$ 的组合爆炸,引发代码中大量的硬编码匹配分支。
|
||
|
||
### 1.3 `runner.rs` 与 `executor.rs` 的硬编码耦合问题
|
||
|
||
现存节点端代码将执行顺序与文件依赖硬编码,例如必须检查 `TaskType::SeedStep` 才能下载大气文件,无法灵活应对只运行光谱合成的场景。
|
||
|
||
---
|
||
|
||
## 2. 独立阶段配置架构设计 (Stage-Based Independent Configuration)
|
||
|
||
为了实现极高的灵活性并彻底避免组合爆炸,摒弃全局单一的 `TaskType` 枚举绑定,将 TLUSTY 和 SYNSPEC 视为平级的**独立阶段 (Stage)**。
|
||
|
||
对每一个计算阶段,均提供正交的三个配置维度:
|
||
|
||
1. **启用开关 (Enabled)**:布尔值,决定当前任务流是否要执行该阶段。
|
||
2. **执行策略 (Execution Policy)**:启动工作流时对历史终态点的处理逻辑(跳过收敛/重试失败、强制重算、跳过收敛及失败)。注意:策略只决定**启动时**对终态点的处理;失败后的策略链回退由策略链(§4.2)独立驱动,不受策略门控(2026-08-04 语义修正)。
|
||
3. **计算策略 (Compute Strategy)**:该阶段所采用的具体科学计算方法。
|
||
|
||
### 2.1 独立阶段正交模型
|
||
|
||
**阶段一:TLUSTY 大气结构求解**
|
||
|
||
- **Enabled**: `true` / `false`
|
||
- **Policy**: `SkipConverged` (默认:跳过收敛·重试失败) / `ForceRecompute` (全量重算) / `SkipFailed` (跳过收敛及失败)
|
||
- **Strategy**: `ColdRun` (冷启动) / `SeedStep` (种子推演)(系统已预留扩展其他策略如网格内插的接口)
|
||
|
||
**阶段二:SYNSPEC 光谱合成**
|
||
|
||
- **Enabled**: `true` / `false`
|
||
- **Policy**: `SkipConverged` / `ForceRecompute` / `SkipFailed`
|
||
- **Strategy**: `Standard` (标准)(系统已预留扩展如多分辨率展宽、线表扫描等策略接口)
|
||
|
||
### 2.2 典型场景映射
|
||
|
||
此设计允许前端灵活组装出任意复杂度的科研计算流:
|
||
|
||
- **场景 A(新网格生成)**:TLUSTY [启用, 增量, ["cold_run", "seed_step"]] + SYNSPEC [启用, 增量, ["standard"]]
|
||
- **场景 B(仅更新光谱)**:TLUSTY [关闭] + SYNSPEC [启用, 强制重算, ["standard"]]
|
||
- **场景 C(强制更新大气)**:TLUSTY [启用, 强制重算, ["seed_step"]] + SYNSPEC [关闭]
|
||
|
||
---
|
||
|
||
## 3. 数据模型与阶段配置结构设计 (Domain Model)
|
||
|
||
在底层核心结构 (`TaskSpec`) 中,我们将原有的单级平铺类型彻底废弃,转而采用**嵌套式单阶段配置模型 (`EngineStageConfig`)**(注:为避免与 `common::config::StageConfig` 迭代步进参数同名冲突,阶段配置统命名为 `EngineStageConfig`)。
|
||
|
||
- **`EngineStageConfig` 结构说明**:
|
||
每一个阶段(无论是 TLUSTY 还是 SYNSPEC)都会拥有一个独立的 `EngineStageConfig` 对象,包含以下三个核心字段:
|
||
|
||
1. `enabled`: 布尔值。是否在当前计算流中启用该阶段。
|
||
2. `policy`: 枚举。决定**启动工作流时**对历史终态点的处理,可选值为:
|
||
- `SkipConverged`: 跳过已收敛、重试已失败(启动时把失败点打回 pending 重试,收敛点保留)。
|
||
- `ForceRecompute`: 强制重算(启动时收敛 + 失败全部打回 pending,无视历史状态与产物)。
|
||
- `SkipFailed`: 跳过收敛及失败(启动时收敛和失败点都保留,只算从未计算过的点)。
|
||
- 失败后的策略链回退不受策略门控,只由 `strategies` 链(回退优先级排序)驱动。
|
||
3. `strategies`: 策略链队列。存储该阶段的计算策略组合,例如 `[ColdRun, SeedStep]`。
|
||
- **`TaskSpec` 根模型重构**:
|
||
原有的 `task_type` 被标记为向后兼容保留字段,新增了:
|
||
|
||
- `tlusty_config`: 对应 TLUSTY 阶段的 `EngineStageConfig` 实例。
|
||
- `synspec_config`: 对应 SYNSPEC 阶段的 `EngineStageConfig` 实例。
|
||
- 保留旧版 `task_type` 作为废弃兼容字段,主要用于 Serde 反序列化历史遗留任务或在途 MQ 消息,并在 `normalize_compat()` 方法中自动映射到新的嵌套结构。
|
||
|
||
---
|
||
|
||
## 4. 数据库与流转设计 (Database & Scheduler Lifecycle)
|
||
|
||
### 4.1 数据库结构升级
|
||
|
||
任务表 (`tasks`) 需要打平阶段配置,彻底移除阶段绑定关系。
|
||
|
||
- **新增阶段控制字段**:
|
||
|
||
- 为 TLUSTY 新增 `tlusty_enabled` (布尔)、`tlusty_policy` (文本)、`tlusty_strategies` (JSON 数组,默认 `["cold_run"]`)。
|
||
- 为 SYNSPEC 新增 `synspec_enabled` (布尔)、`synspec_policy` (文本)、`synspec_strategies` (JSON 数组,默认 `["standard"]`)。
|
||
- 新增 `atmosphere_ref` 用于显式关联大气网格点。
|
||
- **移除冗余旧字段**:
|
||
|
||
- 在数据库层面移除旧的 `task_type` 列(或保留为 NULL 兼容列)。注:原数据库并无 `pipeline_scope` 列,无需清理。
|
||
|
||
### 4.2 Strategy Chain 自动链式回退机制 (Scheduler-Level)
|
||
|
||
原本硬编码在 `config.yaml` 中的 `seed_step_fallback` 逻辑,在本次重构中**升级为更为通用的“策略链 (Strategy Chain)”机制 (`tlusty_strategies`)**。用户可以选择一个或多个策略并排序,形成执行队列。
|
||
|
||
它的工作流如下:
|
||
|
||
1. **节点执行当前策略**:Node 接收到任务后,总是读取并执行队列中的第一个策略(例如 `tlusty_strategies[0]` 为 `ColdRun`)。
|
||
2. **失败上报**:当该策略执行失败时,Node 向 Server 报告任务失败 (`Failed`)。
|
||
3. **调度介入弹出队列**:Server 接收到失败报告后,检查 `tasks` 表中的 `tlusty_strategies` 数组。
|
||
- 若数组中只有一个元素,说明策略链耗尽,任务彻底失败。
|
||
- 若数组中还有后续元素(如 `[ColdRun, SeedStep]`),Server 会将失败的 `ColdRun` 从队列中弹出。
|
||
4. **生成新任务指令**:Server 将该网格点重置为 `Pending` 状态,并为其生成**下一顺位策略**的任务指令:
|
||
- `tlusty_strategies: ["seed_step"]` (剩下的策略链)
|
||
- **不修改**原有的 `tlusty_policy` 字段(保持用户的初始配置,避免状态污染)。策略链回退只由策略链驱动(2026-08-04 语义修正:移除策略门控);若用户不想重试失败点,用单策略链(如 `["cold_run"]`)+ `SkipFailed` 表达。
|
||
- `seed_point_name: 'xxx'` (如果是 SeedStep,Server 在此时负责在全局网格中寻找已收敛邻居点并注入)
|
||
5. **节点无感知执行**:Node 再次拉取到任务时,继续单纯地执行当前队列头部的 `SeedStep` 策略即可。Node 在准备运行新策略前,会自动清理该网格点上一轮策略留下的故障标记;节点对“回退过程”完全无感知,实现了全局调度与局部计算的完美解耦。
|
||
|
||
注:`synspec_strategies` 的自动弹栈与回退机制与 TLUSTY 保持完全一致(若配置了多策略链)。
|
||
|
||
---
|
||
|
||
## 5. 节点 Runner 与沙箱执行逻辑 (Node Executor)
|
||
|
||
在 DCTS 架构中,Node 采用**单任务独立沙箱 (`data/work/task_<task_id>`)** 执行流,并在完成后清理沙箱 (`cleanup_slot_work_dir`)。Server 端的 Scheduler 在生成 `TaskSpec` 时已依据网格数据库状态计算好当前任务指令,Node 仅需依指令执行:
|
||
|
||
1. **TLUSTY 阶段沙箱执行**:
|
||
|
||
- 首先判断 `tlusty_config.enabled` 开关。若为 `false` 则跳过 TLUSTY 阶段。
|
||
- 若开启,Node 读取 `tlusty_config.strategies` 数组的第一项策略。
|
||
- 若策略为 `SeedStep`,Node 凭 `seed_point_name` 自动向 Server API 异步下载种子 `.7` 大气文件并放入沙箱工作目录,随后调用 `ExecutionRunner` 启动 TLUSTY 迭代计算。
|
||
2. **SYNSPEC 阶段沙箱执行**:
|
||
|
||
- 独立判断 `synspec_config.enabled` 开关。若为 `false` 则跳过。
|
||
- 若开启,Node 校验当前沙箱或关联的大气产物是否存在:若 TLUSTY 阶段刚完成则直接复用沙箱内 `.7` 文件;若为单独运行 SYNSPEC 场景(TLUSTY 关闭),Node先查看本地result目录是否有.7文件并复制到沙箱,如果没有再 凭 `atmosphere_ref`(或 `point_name`)自动向 Server/存储拉取目标 `.7` 文件放入沙箱。
|
||
- 读取 `synspec_config.strategies` 的第一项策略(如 `Standard`),调用 SYNSPEC 二进制进程合成光谱,并按照白名单将结果归档至result。
|
||
|
||
这种沙箱无状态机制完美切合节点端的生命周期,既保证了节点的干脆利落,又实现了与服务端全局调度的彻底解耦。
|
||
|
||
---
|
||
|
||
## 6. 前端 Dashboard 设计 (UI Design)
|
||
|
||
针对恒星大气网格工作流的主页 UI 进行大幅精简与重构。
|
||
|
||
### 6.1 移除冗余组件
|
||
|
||
- **移除卡片下方操作按钮**:彻底删除每个工作流卡片下方的“YAML配置”、“启动”、“暂停”等老旧按钮,工作流的启动配置将收敛至全新的内嵌配置面板。
|
||
- **移除收敛手段归因图表**:删除工作流首页中缺乏实际参考价值的“收敛手段归因”模块,为全新的任务调度引擎配置面板腾出空间。
|
||
|
||
### 6.2 工作流内嵌启动面板 (Embedded Task Configuration Panel)
|
||
|
||
不再使用弹窗 (Modal) 形式,而是直接将任务阶段独立配置面板**内嵌**在工作流详情页或首页的卡片内部,给予用户最直观且最大化的自由配置能力。
|
||
|
||
**2026-08 补充**:面板**默认折叠成一行**(标题 + 状态 + 操作按钮:YAML 配置 / 导出 / 暂停 / 删除 / 保存),点「启动配置 ▾」展开——折叠态下主按钮即「启动配置」(展开核对 TLUSTY/SYNSPEC 设置后再点真正的「启动」;工作流运行中该按钮退化为「配置 ▾」,且「启动」仅在展开态出现、避免误触发)。展开后 TLUSTY/SYNSPEC 两张阶段卡**左右并排**(宽屏两列,窄屏自动退化为单列),高度比纵向叠放减半。折叠状态跨轮询保持,展开中的编辑不因折叠丢失。
|
||
|
||
UI 布局草图如下:
|
||
|
||
```
|
||
+-------------------------------------------------------------------------+
|
||
| Workflow Execution Engine: o_star_grid_v1 |
|
||
+-------------------------------------------------------------------------+
|
||
| |
|
||
| [x] TLUSTY Atmosphere Computing Stage |
|
||
| Policy: [ Skip Converged (Incremental) v ] |
|
||
| Strategy Chain (Ordered by fallback priority): |
|
||
| 1. [ Cold Run v ] (X) |
|
||
| 2. [ Seed Step v ] (X) |
|
||
| + Add Fallback Strategy |
|
||
| |
|
||
| --------------------------------------------------------------------- |
|
||
| |
|
||
| [x] SYNSPEC Spectrum Synthesis Stage |
|
||
| Policy: [ Force Recompute v ] |
|
||
| Strategy Chain: |
|
||
| 1. [ Standard v ] (X) |
|
||
| |
|
||
| [ Save Config ] [ Start Grid ] |
|
||
+-------------------------------------------------------------------------+
|
||
```
|
||
|
||
前端 Payload 发送格式:
|
||
|
||
```json
|
||
{
|
||
"tlusty_config": {
|
||
"enabled": true,
|
||
"policy": "skip_converged",
|
||
"strategies": ["cold_run", "seed_step"]
|
||
},
|
||
"synspec_config": {
|
||
"enabled": true,
|
||
"policy": "force_recompute",
|
||
"strategies": ["standard"]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 兼容与部署限制(2026-08 审查补充)
|
||
|
||
### 7.1 滚动升级约束:阶段开关需全集群新节点
|
||
|
||
`task_type` 兼容字段只向后兼容 TLUSTY 策略(`cold_run` / `seed_step`)——旧节点仍能据此
|
||
区分冷启动与种子步进。但 **`enabled` 阶段开关无法传达给旧节点**:
|
||
|
||
- TLUSTY-only 工作流(`synspec_stage.enabled: false`)在旧节点上仍会执行光谱合成;
|
||
- SYNSPEC-only 工作流(`tlusty.enabled: false`)在旧节点上被当作普通 cold_run+synspec 任务,
|
||
语义退化(需自带种子/大气才能成功)。
|
||
|
||
因此启用**阶段开关**(非默认双开)的工作流,须确保集群内全部节点已升级到支持阶段配置的
|
||
版本,否则节点行为与工作流意图不符。纯默认配置(双阶段启用)不受影响。
|
||
|
||
### 7.2 policy 决策取派发时快照(不随 YAML 漂移)
|
||
|
||
策略链回退(§4.2)的**策略链**与回退任务继承的 policy 均取**派发时落库的 DB 快照**
|
||
(`tasks` 表的 `*_policy` / `*_strategies` 列,见 `FallbackSnapshot`),与 §4.2「不修改原有
|
||
policy,保持用户初始配置」语义一致。2026-08-04 起策略不再门控回退(回退只由策略链驱动),
|
||
但 policy 仍随重试任务落库,供审计与下次启动时的策略重置逻辑消费。数值参数
|
||
(`synspec: {wstart/wend/...}`、`timeout_sec`)仍取当前 YAML(用户编辑意图优先),形成
|
||
「旧链 / 旧 policy + 新数值参数」的混合口径——这是有意取舍:策略链与 policy 是任务级
|
||
回退语义记录必须用派发时的,运行参数允许跟随最新配置。
|
||
|
||
### 7.3 完整 YAML 编辑器(数值参数编辑通道)已恢复
|
||
|
||
内嵌面板(§6.2)只编辑阶段三维配置(enabled / policy / strategies);`synspec:` 数值参数块
|
||
(波长范围、展宽、截断等)不在面板编辑范围。**2026-08 补充**:引擎面板新增「YAML 配置」按钮,
|
||
恢复原 `yamlEditor.js` 的完整 YAML 查看/编辑弹窗(语法高亮 + 行号 + 脏状态守卫 + 运行中锁定 +
|
||
服务端校验错误内联横幅),数值参数等完整配置均可在此查看与修改后直接保存(PUT
|
||
/api/workflows/:name)。该弹窗与内嵌面板的保存互相独立、以各自编辑内容为准——二者维度正交:
|
||
面板管执行语义(阶段开关/策略),弹窗管完整配置(含数值参数)。
|