将 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 笔误
import_results
DCTS 历史计算结果导入工具。把旧版 Python 单机
run_grid.py/run_one.py的计算结果 完整迁移到当前分布式系统,避免重算已完成的网格点。
📦 模块概览
import_results 承担双职责:
- 入库 + 种子库:经服务端
/api/admin/import_seed把旧版的收敛结果(conv.json+.7大气文件)上传,把grid_points标记为converged。这样启动工作流时这些点会被跳过, 不再重复计算。 - 完整产物树迁移:把旧目录的全部产物文件,按新版 node result 格式 + workflow 配置
的小数精度命名,拷贝到本地
data/result/<name>/。docker-compose 里 server/node 都挂载./data:/app/data,node 的DCTS_RESULT_DIR=/app/data/result,故工具在服务器宿主机 运行即可被 node 识别为已有结果归档。
命名以 workflow 配置为准:GridConfig::from_yaml_str 保留 YAML 源小数精度(如
logg: 5.0 → g5.0),而非旧 conv.json 里的 name。
🚀 编译
cargo build -p import_results --release
使用示例
# 完整导入(产物树 + 入库)
./target/release/import_results \
--dir /旧数据/results \
--config workflows/sdB_cno.yaml \
--result-dir data/result \
--server http://127.0.0.1:8090 \
--workflow sdB_cno \
--token <admin_token>
参数说明
| 参数 | 说明 |
|---|---|
-d/--dir <dir> |
旧版 run_grid.py 的 results 根目录(默认 data/results) |
-c/--config <yaml> |
必填。workflow 配置,用于推导权威命名 + 校验网格点 |
-r/--result-dir <dir> |
产物树写入目标(默认 data/result,与 node 的 DCTS_RESULT_DIR 同卷)。旧长名 --archive-dir 仍兼容(仅长选项) |
-s/--server <url> |
服务端 API 地址(默认 http://127.0.0.1:8090) |
-w/--workflow <name> |
必填。目标工作流名,必须等于将来要启动的工作流名 |
-t/--token <token> |
服务端 Admin 鉴权令牌 |
⚠️ 关键注意事项
1. -w 工作流名必须匹配将来要启动的工作流
grid_points 唯一键是复合 (workflow_name, name),工作流强隔离。若导入到工作流 A,
之后启动工作流 B,B 看不到 A 的 converged 标记,会重算全部已算过的点。
正确顺序:
# 1. 先导入(-w = 目标工作流名)
./import_results -d /旧数据/results -c workflows/sdB_cno.yaml -w sdB_cno ...
# 2. 在 Dashboard 用同名配置创建工作流 sdB_cno
# 3. 启动 sdB_cno
# → initialize_grid 对已导入点 DO NOTHING(保留 converged,跳过重算)
# → 对配置里有但旧数据没有的新点,插入 pending(正常计算)
2. 文件名映射规则(旧 → 新 result 格式)
| 旧文件 | 新文件 |
|---|---|
conv.json |
conv.json |
<old>.7/.spec/.cont/.iden/.log |
<new>.7/.spec/.cont/.iden/.log |
<old>.lte.7/.nc.7/.nl.7 |
<new>.lte.7/.nc.7/.nl.7 |
<old>.nc_chmax0p001_itekNone.9 |
<new>.nc_chmax0.001.9 |
<old>.5/.6(旧版只留最后阶段) |
<new>.nl.5/.nl.6 |
fort.8 |
fort.8 |
跳过:迁移后的文件名统一经结果白名单(common::result_filter::is_result_worthy,
与 node 实时结果归档共用同一份判别规则)复核。不在白名单内的一律跳过,包括:
- 软链(
data/fort.19) fort.84、*.tmp- 新版已清理的裸文件(
nst/fort.9/fort.12/fort.17,内容已被.iden/.cont/_chmax.9覆盖) - Tlusty 中间工作单元(
fort.1/2/3/13/14/18/22/42/44/50/57/69/82/95等,无语义价值) - 无
_chmax的.9阶段快照(与<name>.<label>_chmax*.9内容重复,唯一保留_chmax.9)
旧版因「每阶段覆盖」丢失的中间阶段 .5/.6/.err/.nst(只留最后 nl 阶段)无法重建,
归到 .nl. 标签下。
3. 导入数据的字段去向
| 旧 conv.json 字段 | 落库位置 | 展示 |
|---|---|---|
name(被工具重写为配置权威名) |
grid_points.name |
点表/详情 |
converged && !atmosphere_has_nan |
grid_points.status='converged' |
状态徽章 |
| —(固定值) | grid_points.success_method='imported' |
方法徽章"导入" |
final_max_relc |
种子库记录 + conv.json 原文 | 点详情 |
elapsed_sec |
grid_points.last_elapsed_sec |
点表"耗时"列 |
全文(含 stages[].itek_attempts/final 嵌套诊断) |
seeds_dir/<name>/conv.json 原文 |
点详情阶段链(扁平字段兼容解析,嵌套诊断原文保留不丢失) |
旧版 stage 的迭代诊断(last_iter 等)嵌在 final/itek_attempts 里而非扁平字段,
详情页阶段链不显示迭代数,但原始数据随 conv.json 原文完整保留。