feat(all): 源精度命名体系、工作流可观测台、节点停用管理与白名单归档
核心变更:
1. GridAxisValue 源精度命名
- 新增 GridAxisValue 类型,携带 f64 数值 + YAML 源书写文本(Deref 透明兼容算术)
- config.rs 绕过 serde_yaml 归一化,逐 token 捕获轴值原文(logg: 5.0 → g5.0)
- runner/executor/scheduler 全链路改用 DB TEXT 列权威 point_name,
修复 REAL 列回读丢精度导致的 model_name 错配
2. 工作流执行可观测台
- 新增 stats/progress/points 三组 API(进度时间序列、经验速率 ETA、
停滞预警、逐点明细分页、收敛性热力图数据)
- 新增 workflow_progress_snapshots 表 + tasks/grid_points 耗时列
- runner 携带 last_iter/worst_depth/n_depths 进 conv.json
- 前端新增 hash 路由、工作流详情页(概览/网格点/收敛分析三 Tab)、YAML 编辑器
3. 节点停用/启用管理
- 新增 disabled 状态 + disable/enable API;停用节点保持心跳但停止分发,
worker 空闲待命而非退出;移除 revoke API,token 失效统一走重发覆盖;
移除 host_name 字段
4. 白名单结果归档
- 新增 result_filter 模块,只归档有语义产物,丢弃 Tlusty 中间单元(~2MB/模型)
- executor 原子写入归档 + 200 点 LRU 上限
5. 历史数据导入
- sync_seeds 重写为 import_results:经 /admin/import_seed 标记 converged +
按新版命名迁移产物树
6. 部署与目录重规划
- data/results→seeds、data/archive→result + migrate_data_dirs.sh
- deploy.sh 增强(SSH 复用、Profile、远程 env);Dockerfile 瘦身
7. 文档同步更新 api/database/architecture/deployment
This commit is contained in:
+53
-40
@@ -9,55 +9,64 @@
|
||||
```mermaid
|
||||
erDiagram
|
||||
WORKFLOWS ||--o{ GRID_POINTS : contains
|
||||
GRID_POINTS ||--o{ TASK_HISTORY : logs
|
||||
GRID_POINTS ||--o{ TASKS : logs
|
||||
NODES ||--o{ TASK_QUEUE : executes
|
||||
|
||||
subgraph PrimaryDB ["主数据库 (dcts.db)"]
|
||||
WORKFLOWS {
|
||||
string name PK
|
||||
string description
|
||||
text yaml_config
|
||||
text config_yaml
|
||||
string status
|
||||
datetime created_at
|
||||
datetime updated_at
|
||||
}
|
||||
GRID_POINTS {
|
||||
string point_id PK
|
||||
string name PK
|
||||
string workflow_name FK
|
||||
double teff
|
||||
double logg
|
||||
double he_abund
|
||||
double c_abund
|
||||
double n_abund
|
||||
double o_abund
|
||||
double loghe
|
||||
double logc
|
||||
double logn
|
||||
double logo
|
||||
double cno_sum
|
||||
integer wave
|
||||
string status
|
||||
datetime updated_at
|
||||
integer attempt_count
|
||||
string success_method
|
||||
}
|
||||
TASK_HISTORY {
|
||||
string id PK
|
||||
string point_id FK
|
||||
TASKS {
|
||||
string task_id PK
|
||||
string point_name FK
|
||||
string node_id
|
||||
boolean success
|
||||
text conv_info_json
|
||||
datetime duration_sec
|
||||
string task_type
|
||||
string status
|
||||
double max_relc
|
||||
integer retry_count
|
||||
datetime created_at
|
||||
}
|
||||
NODES {
|
||||
string node_id PK
|
||||
string hostname
|
||||
integer cpu_cores
|
||||
integer max_slots
|
||||
integer active_slots
|
||||
string status
|
||||
double cpu_usage
|
||||
double memory_usage
|
||||
datetime last_heartbeat
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
subgraph QueueDB ["队列库 (dcts_queue.db / mq)"]
|
||||
TASK_QUEUE {
|
||||
string task_id PK
|
||||
string workflow_name
|
||||
string payload_json
|
||||
string payload
|
||||
string status
|
||||
string assigned_node
|
||||
integer retry_count
|
||||
datetime created_at
|
||||
datetime claimed_at
|
||||
string workflow_name
|
||||
string claimed_by_node_id
|
||||
integer wave
|
||||
}
|
||||
end
|
||||
```
|
||||
@@ -68,11 +77,11 @@ erDiagram
|
||||
|
||||
### 2.1 `workflows` (工作流配置表)
|
||||
存储用户定义的计算网格配置及整体状态。
|
||||
- `name` (`VARCHAR(64) PRIMARY KEY`):工作流唯一标志(如 `sdB_cno`)。
|
||||
- `name` (`TEXT PRIMARY KEY`):工作流唯一标志(如 `sdB_cno`)。
|
||||
- `description` (`TEXT`):描述信息。
|
||||
- `yaml_config` (`TEXT`):完整的参数网格定义与物理配置 YAML 内容。
|
||||
- `status` (`VARCHAR(32)`):状态:`idle` / `running` / `paused` / `completed`。
|
||||
- `created_at` (`DATETIME DEFAULT CURRENT_TIMESTAMP`):创建时间。
|
||||
- `config_yaml` (`TEXT NOT NULL`):完整的参数网格定义与物理配置 YAML 内容。
|
||||
- `status` (`TEXT NOT NULL DEFAULT 'idle'`):`idle`(就绪)→ `initializing`(原子抢占加载中)→ `running`(运行中)/ 回退 `idle`;`running` → `paused`(暂停)/ `completed`(全部网格点收敛)。
|
||||
- `created_at` / `updated_at` (`DATETIME NOT NULL`):创建 / 最后更新时间。
|
||||
|
||||
### 2.2 `grid_points` (网格点物理参数表)
|
||||
存储多维笛卡尔积展开后的每一个独立参数点。
|
||||
@@ -93,26 +102,30 @@ erDiagram
|
||||
> 标记为 `__legacy__`,不干扰新工作流查询。
|
||||
|
||||
### 2.3 `nodes` (计算节点心跳与状态表)
|
||||
- `node_id` (`VARCHAR(64) PRIMARY KEY`):节点唯一标识。
|
||||
- `hostname` (`VARCHAR(128)`):节点主机名或 IP。
|
||||
- `cpu_cores` (`INTEGER`):节点 CPU 核心数。
|
||||
- `status` (`VARCHAR(32)`):`online` / `offline` / `busy`。
|
||||
- `last_heartbeat` (`DATETIME`):最后一次心跳上报时间。
|
||||
- `node_id` (`TEXT PRIMARY KEY`):节点唯一标识(未指定 `DCTS_NODE_ID` 时自动生成 `node-<uuid>`)。
|
||||
- `max_slots` (`INTEGER NOT NULL`):节点声明的最大并发计算槽位数(即 `DCTS_MAX_SLOTS`,领用上限)。
|
||||
- `active_slots` (`INTEGER NOT NULL DEFAULT 0`):当前正在执行的任务数,随 claim 自增、report 完结自减。
|
||||
- `status` (`VARCHAR(32) NOT NULL DEFAULT 'online'`):`pending_approval`(注册待审批)/ `online`(在线)/ `offline`(心跳超时离线)/ `disabled`(管理员手动停用,保持心跳但不再分发任务)/ `rejected`。
|
||||
- `cpu_usage` / `memory_usage` (`REAL NOT NULL DEFAULT 0.0`):心跳上报的 CPU/内存使用率(仅观测展示用,**不参与任务分发决策**)。
|
||||
- `last_heartbeat` (`DATETIME NOT NULL`):最后一次心跳上报时间,后台线程据此判定 `online → offline`。
|
||||
|
||||
### 2.4 `task_queue` (分布式任务队列表 - `mq`)
|
||||
驱动分布式抢占与超时重试的核心表,使用 SQLite `WAL` 模式确保高吞吐并发安全。
|
||||
- `task_id` (`VARCHAR(128) PRIMARY KEY`):任务 ID。
|
||||
- `workflow_name` (`VARCHAR(64)`):工作流。
|
||||
- `payload_json` (`TEXT`):任务所含参数 payload。
|
||||
- `status` (`VARCHAR(32)`):`pending`(就绪) / `running`(计算中) / `completed`(完成) / `failed`(失败)。
|
||||
- `assigned_node` (`VARCHAR(64)`):当前抢占该任务的节点 ID。
|
||||
- `retry_count` (`INTEGER DEFAULT 0`):失败或超时重发次数。
|
||||
- `claimed_at` (`DATETIME`):抢占时间戳(用于超时释放判定)。
|
||||
驱动分布式抢占与超时重试的核心表,使用 SQLite `WAL` 模式确保高吞吐并发安全(详见 [`sqlite_queue.rs`](file:///home/fmq/program/tlusty/tl208-s54/dcts/crates/mq/src/sqlite_queue.rs#L65))。
|
||||
- `task_id` (`VARCHAR(128) PRIMARY KEY`):任务 ID(UUID)。
|
||||
- `payload` (`TEXT NOT NULL`):序列化的 [`TaskSpec`](file:///home/fmq/program/tlusty/tl208-s54/dcts/crates/common/src/models.rs)(含 point_name / params / task_type / seed_point_name / workflow_name 等)。
|
||||
- `status` (`TEXT NOT NULL`):`pending`(就绪待领用)/ `claimed`(已被某 node 领用,计算中)。
|
||||
- `created_at` (`DATETIME NOT NULL`):推入队列时间(同 `wave` 内 FIFO 排序键)。
|
||||
- `claimed_at` (`DATETIME`):被领用的时间戳(`requeue_stale_tasks` 据此判定超时回投)。
|
||||
- `workflow_name` (`TEXT`):所属工作流(多工作流分区键)。
|
||||
- `claimed_by_node_id` (`TEXT`):领用方节点 ID(claim 时写入,report 阶段据此校验归属,防跨节点伪造)。
|
||||
- `wave` (`INTEGER NOT NULL DEFAULT 0`):难度波次(`pop_task` 出队第一排序键,低 `wave` 优先)。
|
||||
|
||||
> 任务完成后由 `remove_task` 直接从本表删除(不保留 `completed`/`failed` 终态行),历史记录落在主库 `tasks` 表。超时的 `claimed` 行由 [`requeue_stale_tasks`](file:///home/fmq/program/tlusty/tl208-s54/dcts/crates/mq/src/sqlite_queue.rs#L274) 改回 `pending` 重投。
|
||||
|
||||
---
|
||||
|
||||
## 3. 并发与事务安全设计
|
||||
|
||||
1. **WAL (Write-Ahead Logging) 模式**:SQLite 连接自动启用 `PRAGMA journal_mode=WAL;` 和 `PRAGMA busy_timeout=5000;`,解决多线程/多进程读写锁竞争。
|
||||
1. **WAL (Write-Ahead Logging) 模式**:SQLite 连接自动启用 `PRAGMA journal_mode=WAL;` 和 `PRAGMA busy_timeout=15000;`,解决多线程/多进程读写锁竞争。
|
||||
2. **连接池机制**:借助 `r2d2` + `r2d2_sqlite` 维护异步连接池,防止高并发下数据库句柄冲突。
|
||||
3. **原子 Claim 事务**:任务抢占在单个 SQLite 事务中完成(`UPDATE task_queue SET status='running', assigned_node=? WHERE status='pending' ... LIMIT 1`),保证绝对防重领。
|
||||
3. **原子 Claim 事务**:任务抢占在单个 `IMMEDIATE` 事务内完成——先 `SELECT ... WHERE status='pending' ORDER BY wave ASC, created_at ASC LIMIT 1` 取队首,再 `UPDATE SET status='claimed', claimed_by_node_id=?`,提交后返回。事务保证同一任务不会被两个 node 同时领用;遇到 `SQLITE_BUSY/LOCKED` 最多退避重试 5 次(详见 [`pop_task`](file:///home/fmq/program/tlusty/tl208-s54/dcts/crates/mq/src/sqlite_queue.rs#L145))。
|
||||
|
||||
Reference in New Issue
Block a user