feat(all): 数据库模块化拆分与版本化迁移、任务引擎命名体系收敛、物理输出校验加固与用户配置接通
- server/db: 拆 4929 行 db.rs 单体为 db/ 目录,migrations.rs 引入 PRAGMA user_version
版本化迁移运行器(M1~M13)
- 任务引擎 Phase 6/7b/7c 改名收敛:EngineStageConfig→PhaseConfig、StagePolicy→ResumePolicy、
Converged→Completed、删除 task_type 列、success_method 拆 tlusty_/synspec_ 双列、
新增 tlusty_status/synspec_status 半失败阶段守卫
- 科学正确性加固:conv_check 任意行 NaN/Inf/溢出判无效(0 行容忍)、新增 spec_is_valid
校验 SYNSPEC 脏谱、itek_history 逐次迭代全量保真、fmt_abn powf 溢出饱和
- 用户配置真正接通:tlusty_chain/tlusty_input 由死字段经 调度器→TaskSpec→executor→runner
透传生效;config 加载期 validate + deny_unknown_fields + 解析失败记 warn
- 调度修复:H1 活锁(pending_strategies 跳过已失败策略)、种子查找错误不再静默降级冷启动
- dashboard: 阶段配置面板 tlusty_stage/synspec_stage、"已完成"标签、迭代诊断展示
- docs: 新增 database_refactor_design.md,同步 database/api/PIPELINE/workflow_detail
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
> - **未实现**:§2.2/§2.4 的「重试失败点」按钮与 `POST .../points/retry` 端点
|
||||
> (前后端均未实现)。
|
||||
> - **方法归因**:`imported` 不再作为独立收敛途径(导入点按 seed_step 统计),
|
||||
> `success_method` 过滤白名单仅 `cold_run` / `seed_step`。
|
||||
> 大气方法过滤白名单 `cold_run` / `seed_step`(映射 `tlusty_success_method`);另有 `synspec_only` 光谱专用点过滤器(`tlusty IS NULL AND synspec IS NOT NULL`)。
|
||||
|
||||
---
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
| 数据 | 位置 | 说明 |
|
||||
|---|---|---|
|
||||
| 网格点 6 维参数、`cno_sum`、`wave` | `grid_points` 表(`db.rs:246-263`) | 按 `workflow_name` 分区,复合唯一 `(workflow_name, name)` |
|
||||
| 点状态 `pending/queued/running/converged/failed` | `grid_points.status` | `GridPointStatus`(`models.rs:235-243`) |
|
||||
| **成功手段** `cold_run` / `seed_step` / `imported` | `grid_points.success_method` | 收敛时由成功任务的 `task_type` 回填(`db.rs:1097-1101`);失败点为 NULL |
|
||||
| 点状态 `pending/queued/running/completed/failed`(`completed` 由 7c 改名自 `converged`) | `grid_points.status` | `GridPointStatus`(`models.rs:235-243`) |
|
||||
| **大气成功手段** `cold_run` / `seed_step` / `imported` | `grid_points.tlusty_success_method` | TLUSTY 阶段收敛时由成功任务的 `tlusty_strategies[0]` 派生回填(Phase 6 起 `task_type` 列已删除);TLUSTY 禁用(synspec-only)为 NULL。光谱阶段另存 `synspec_success_method`(Phase 5a,取 `synspec_strategies[0]`)。整体归因由消费方派生 `tlusty ?? synspec`(P9 拆分,原 `success_method` 值域混用列已删) |
|
||||
| 重试次数 | `grid_points.attempt_count` | 每次回报 +1(`db.rs:1089-1095`) |
|
||||
| 每次尝试的收敛指标 | `tasks.max_relc` | 收敛判据 `max_relc < chmax`(默认 0.001,`conv_check.rs:105-109`) |
|
||||
| **每次尝试的种子来源** | `tasks.seed_point_name` | 派发时写入(`scheduler.rs:194-205`) |
|
||||
| 每次尝试的方法 / 错误 / 节点 / 完成时间 | `tasks.task_type / error_message / node_id / completed_at` | 一个点多行(每次尝试一行),工作流删除前长期保留 |
|
||||
| 每次尝试的方法 / 错误 / 节点 / 完成时间 | `tasks.tlusty_strategies[0] / error_message / node_id / completed_at` | 一个点多行(每次尝试一行),工作流删除前长期保留;方法取自策略链首项(`task_type` 列已删) |
|
||||
| 全局种子库 | `seeds` 表 + `data/seeds/<name>/<name>.7` | 仅收敛且无 NaN 的点入库(`task.rs:187-207`) |
|
||||
| **逐阶段完整诊断**(lte→nc→nl / seed_nc→nl) | `data/seeds/<name>/conv.json` | `ModelSummary`(`models.rs:376-391`):每阶段 `converged / best_max_relc / chmax / elapsed_sec`、总耗时、`synspec_sec`、所用种子。**成功与失败的点都会写**(`task.rs:178-184`) |
|
||||
| 按工作流的统计聚合 | `db.get_grid_summary_stats(Some(wf))` | **已实现且有单测**(`db.rs:1582-1639`),但没有任何 HTTP 端点调用它 |
|
||||
@@ -67,7 +67,7 @@
|
||||
所以"哪些参数冷启动能成功" ≈ 低 cno_sum / 中低温区的点;高温 He-poor 区几乎全靠种子步进。
|
||||
- **还有一次性失败回退**:冷启动发散且存在邻居种子时,自动以 `seed_step` 重投一次
|
||||
(`scheduler.rs:270-350`,受 `seed_step_fallback` 配置与 `has_seed_step_attempt` 一次性闸门约束)。
|
||||
因此 `success_method='seed_step'` 的点可能是"冷启动失败后被救回"的——该归因需从 `tasks` 多行历史还原。
|
||||
因此 `tlusty_success_method='seed_step'` 的点可能是"冷启动失败后被救回"的——该归因需从 `tasks` 多行历史还原。
|
||||
- **第三类 `imported`**:历史 `run_grid.py` 结果导入(`db.rs:966-981`),UI 需单独呈现为"历史导入"。
|
||||
- **收敛判据**:末次迭代最差深度点的最大相对修正 `max_relc < chmax`(默认 1e-3),
|
||||
且大气 NaN 占比 ≤ 10%(`conv_check.rs:127-149`)。
|
||||
@@ -215,9 +215,9 @@
|
||||
"data": {
|
||||
"name": "sdB_cno", "status": "running",
|
||||
"total": 432,
|
||||
"pending": 120, "queued": 40, "running": 8, "converged": 261, "failed": 3,
|
||||
"cold_run_converged": 220, "seed_step_converged": 41, "imported_converged": 0,
|
||||
"waves": [ {"wave": 0, "total": 108, "converged": 108, "failed": 0}, ... ],
|
||||
"pending": 120, "queued": 40, "running": 8, "completed": 261, "failed": 3,
|
||||
"cold_run_converged": 220, "seed_step_converged": 41,
|
||||
"waves": [ {"wave": 0, "total": 108, "completed": 108, "failed": 0}, ... ],
|
||||
"avg_point_sec": 740.0, "eta_sec": 9600
|
||||
}
|
||||
}
|
||||
@@ -242,11 +242,11 @@
|
||||
"name": "t60000_g5.0_he-2_c-4_n-4_o-4",
|
||||
"teff": 60000, "logg": 5.0, "loghe": -2, "logc": -4, "logn": -4, "logo": -4,
|
||||
"cno_sum": -12, "wave": 0,
|
||||
"status": "converged", "success_method": "seed_step", "attempt_count": 2,
|
||||
"last_max_relc": 0.00043, "last_task_type": "seed_step",
|
||||
"status": "completed", "tlusty_success_method": "seed_step", "synspec_success_method": "standard", "attempt_count": 2,
|
||||
"last_max_relc": 0.00043,
|
||||
"seed_point_name": "t60000_g5.0_he2_c-4_n-4_o-4",
|
||||
"node_id": "node-a1b2", "last_completed_at": "2026-07-30T11:12:00Z",
|
||||
"elapsed_sec": 126.4
|
||||
"last_elapsed_sec": 126.4
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -256,7 +256,7 @@
|
||||
- "最近一次尝试"用关联子查询取 `tasks` 最新行:
|
||||
|
||||
```sql
|
||||
SELECT gp.*, t.max_relc AS last_max_relc, t.task_type AS last_task_type,
|
||||
SELECT gp.*, t.max_relc AS last_max_relc,
|
||||
t.seed_point_name, t.node_id, t.completed_at AS last_completed_at,
|
||||
t.error_message AS last_error
|
||||
FROM grid_points gp
|
||||
@@ -283,12 +283,13 @@ LIMIT ? LIMIT OFFSET ?;
|
||||
"data": {
|
||||
"point": { /* 同 ② 的单点字段 */ },
|
||||
"attempts": [
|
||||
{"task_id": "...", "task_type": "cold_run", "seed_point_name": null,
|
||||
{"task_id": "...", "seed_point_name": null, // Phase 6 起无 task_type 字段
|
||||
"status": "failed", "max_relc": 954000.0, "atmosphere_has_nan": true,
|
||||
"node_id": "node-a1b2", "error_message": "nl stage diverged...",
|
||||
"created_at": "...", "completed_at": "..."},
|
||||
{"task_id": "...", "task_type": "seed_step", "seed_point_name": "t60000_...",
|
||||
"status": "completed", "max_relc": 0.00043, ...}
|
||||
"failed_stage": "tlusty", "summary_json": "{...}",
|
||||
"created_at": "...", "completed_at": "...", "elapsed_sec": 1800.0},
|
||||
{"task_id": "...", "seed_point_name": "t60000_...", // 第二次尝试(seed_step 热启动救回)
|
||||
"status": "completed", "max_relc": 0.00043, "failed_stage": null, ...}
|
||||
],
|
||||
"conv": { /* data/seeds/<name>/conv.json 解析后的 ModelSummary;文件不在则 null */ }
|
||||
}
|
||||
@@ -304,7 +305,7 @@ LIMIT ? LIMIT OFFSET ?;
|
||||
请求体:`{"names": ["t80000_..."], "all_failed": true}`(二选一)。
|
||||
- 前置:工作流必须 `running`(否则 400,提示"请先启动工作流"——避免重置后无调度器消费的僵尸态)。
|
||||
- 逻辑:新 db 函数 `reset_failed_points(wf, names|all)`:
|
||||
`UPDATE grid_points SET status='pending', success_method=NULL WHERE workflow_name=? AND status='failed' [AND name IN (...)]`,
|
||||
`UPDATE grid_points SET status='pending', tlusty_success_method=NULL, synspec_success_method=NULL WHERE workflow_name=? AND status='failed' [AND name IN (...)]`,
|
||||
随后立即触发一次 `schedule_pending_tasks()`(不必等 30s tick)。
|
||||
- 重试后的方法仍由调度器按种子可用性自动决定(大概率 seed_step,因为此时种子池已更丰富)——
|
||||
这与领域语义一致,前端文案如实说明:"重试的点将由调度器自动选择冷启动或种子步进"。
|
||||
@@ -316,7 +317,7 @@ LIMIT ? LIMIT OFFSET ?;
|
||||
```json
|
||||
{"name": "...", "status": "...", "description": "...",
|
||||
"created_at": "...", "updated_at": "...",
|
||||
"stats": {"total": 432, "converged": 261, "failed": 3, "running": 8,
|
||||
"stats": {"total": 432, "completed": 261, "failed": 3, "running": 8,
|
||||
"cold_run_converged": 220, "seed_step_converged": 41}}
|
||||
```
|
||||
|
||||
@@ -332,7 +333,7 @@ LIMIT ? LIMIT OFFSET ?;
|
||||
2. `StageSummary` 携带 `last_iter / worst_depth / n_depths`(`models.rs:364-373` 扩字段,
|
||||
`runner.rs:302-317` 处 `ConvCheckResult` 已有值,只是没搬过去)→ conv.json 与点详情获得迭代数。
|
||||
3. 新表 `workflow_progress_snapshots(workflow_name TEXT, ts DATETIME, pending INT, queued INT,
|
||||
running INT, converged INT, failed INT)`:由 `main.rs:111-197` 的 30s 后台循环顺手写一行;
|
||||
running INT, completed INT, failed INT)`:由 `main.rs:111-197` 的 30s 后台循环顺手写一行;
|
||||
保留策略:仅当计数相对上次快照有变化才写;定期清理 24h 前的行。供"进度-时间"曲线与精确 ETA。
|
||||
|
||||
### 3.3 明确不做 / 保持现状
|
||||
|
||||
Reference in New Issue
Block a user