Files
DCTS/tools/import_results
fmq c8fd24b120 feat(all): 科学计算正确性修复、调度竞态消除、节点优雅退出、安全加固与收敛分析重构
科学计算正确性:
- 修复 Fortran 无-E 科学记数法(指数≥100 时 E 被挤掉,如 -1.35+118)导致
  发散行被静默跳过、误判收敛的 bug;扩展大气无效检测覆盖 Inf 与 *** 溢出标记
- 种子匹配改为 CNO 有向距离(富金属方向重罚 4×、贫金属方向轻罚 1×),
  基于 1191 个真实种子配对回测标定,回测净改善 314 个点
- GridAxisValue 反序列化拒绝非法文本(不再静默 NaN);chmax≤0 显式报错
- ions 行宽列宽对齐真实 fort.5 格式

调度与队列竞态:
- 原子选点(IMMEDIATE 事务 SELECT+UPDATE)消除并发调度重复派发 (#5)
- 调度互斥锁 + 冷启动优先策略(SeedStep 仅作失败后救援,不再正常路径热启动)
- 毒消息 dead_letter 标记防出队死循环;clear_queue 保留 claimed 行 (#6)
- 孤儿 running 点回收兜底;stale_sec 默认 7800→21600s(3 倍超时缓冲)

节点生命周期:
- SIGTERM+SIGINT 双信号监听(修复 Docker stop 发 SIGTERM 不触发优雅退出)
- SlotGuard RAII 防活动 slot 泄漏;子进程超时增加二级 30s wait 防 Fortran hang
- SeedStep 种子下载 fail-fast + 沙盒私有副本解耦 LRU 清理竞争
- reqwest Client 增加连接/请求超时;启动清理残留 task_* 沙盒

安全加固:
- 节点注册 registration_secret 二次凭据 (H8),恒定时间比对防时序旁路
- token 缓存 generation 机制消除 reissue 后旧 token TOCTOU 复活窗口
- 新增 /api/auth/logout 服务端 session 即时撤销;fail-closed 鉴权启动策略
- 前端 token 迁移 sessionStorage;YAML 高亮改 DOM API 消除 XSS 注入面
- 备份文件权限收紧 0600;点表动态值全面 escapeHtml

前端 Dashboard:
- 收敛性分析从热力图重构为 Parallel Sets 平行集合图(6 维+状态轴,手写 SVG 零依赖)
- 进度曲线横轴改为真实时间(服务端 now 锚定,停滞期诚实留白);轮询指数退避
- 移除 imported 收敛途径分类,导入点按实际途径 cold_run/seed_step 归类
- 初始化时 /api/auth/check 校验 token;401 toast 提示替代静默 reload

服务端恢复与工具链:
- 启动恢复 initializing 态工作流;默认工作流 INSERT-only 不覆盖 API 编辑
- body limit 分层(10MB 不再截断 256MB report);multipart 显式错误处理
- 嵌入二进制原子写(tmp+rename)防半写损坏
- import_results 判定收敛途径透传 success_method;conv.json 格式对齐本项目
- push_import_results.sh 退出码修复 + .bat UTF-8 BOM + scp 上传
- Docker USE_MIRRORS 默认关闭;移除无用 assets 挂载;删除 hosts.ini 入库
2026-08-01 17:01:40 +08:00
..

import_results

DCTS 历史计算结果导入工具。把旧版 Python 单机 run_grid.py/run_one.py 的计算结果 完整迁移到当前分布式系统,避免重算已完成的网格点


📦 模块概览

import_results 承担双职责

  1. 入库 + 种子库:经服务端 /api/admin/import_seed 把旧版的收敛结果(conv.json + .7 大气文件)上传,把 grid_points 标记为 converged。这样启动工作流时这些点会被跳过, 不再重复计算。
  2. 完整产物树迁移:把旧目录的全部产物文件,按新版 node result 格式 + workflow 配置 的小数精度命名,拷贝到本地 data/result/<name>/。docker-compose 里 server/node 都挂载 ./data:/app/datanode 的 DCTS_RESULT_DIR=/app/data/result,故工具在服务器宿主机 运行即可被 node 识别为已有结果归档。

命名以 workflow 配置为准GridConfig::from_yaml_str 保留 YAML 源小数精度(如 logg: 5.0g5.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 之后启动工作流 BB 看不到 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 原文完整保留。