# 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_`)** 执行流,并在完成后清理沙箱 (`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_input`(fort.55 控制卡)、`timeout_sec`)仍取当前 YAML(用户编辑意图优先),形成 「旧链 / 旧 policy + 新数值参数」的混合口径——这是有意取舍:策略链与 policy 是任务级 回退语义记录必须用派发时的,运行参数允许跟随最新配置。 ### 7.3 完整 YAML 编辑器(数值参数编辑通道)已恢复 内嵌面板(§6.2)只编辑阶段三维配置(enabled / policy / strategies);`synspec_input`(fort.55 控制卡)等数值参数块不在面板编辑范围。**2026-08 补充**:引擎面板新增「YAML 配置」按钮, 恢复原 `yamlEditor.js` 的完整 YAML 查看/编辑弹窗(语法高亮 + 行号 + 脏状态守卫 + 运行中锁定 + 服务端校验错误内联横幅),数值参数等完整配置均可在此查看与修改后直接保存(PUT /api/workflows/:name)。该弹窗与内嵌面板的保存互相独立、以各自编辑内容为准——二者维度正交: 面板管执行语义(阶段开关/策略),弹窗管完整配置(含数值参数)。