26 KiB
DCTS (Distributed Computing TLUSTY/SYNSPEC) API 文档
本文档由源代码自动提取并整理,详细说明了 DCTS 分布式恒星大气网格计算系统 服务端 (dcts_server) 提供的所有 RESTful API 接口规范、数据结构定义、鉴权机制、错误码及 curl 调用示例。
目录 (Table of Contents)
- 通用说明与鉴权机制
- 数据结构与类型定义 (Rust & TypeScript Schema)
- 计算节点管理 API (Node Management)
- 任务调度与结果上报 API (Task Processing)
- 种子文件管理 API (Seed Management)
- 静态资源与数据下载 API (Data Assets)
- 系统状态监控 API (System Status)
- 工作流管理 API (Workflow CRUD & Execution)
- 错误处理与状态码汇总
1. 通用说明与鉴权机制
1.1 服务端信息
- 默认服务地址:
http://127.0.0.1:8090(端口可通过--port/DCTS_PORT环境变量配置) - 传输协议: HTTP / HTTPS
- 默认请求/响应格式:
application/json(部分文件下载接口为application/octet-stream,任务上报为multipart/form-data)
1.2 鉴权中间件与抗侧信道机制 (auth_middleware)
服务端在配置了 DCTS_AUTH_TOKEN (或 AppState.auth_token) 时,启用全局 Axum 鉴权中间件。客户端请求需附带正确的 Token,支持以下两种 Header 形式:
- Bearer Token 方式:
Authorization: Bearer <your_auth_token> - X-API-Key 方式:
x-api-key: <your_auth_token>
Tip
防侧信道保护:所有鉴权过程底层完全调用经过高定强优化的恒定长位跨运算度等时比较机制(Constant-Time Comparison),规避了一切从请求响应回车微小毫秒间隔判断探测系统敏感密钥或计算出有效前缀长度的侧信道(Side-Channel Attack)攻击。
若未通过鉴权,服务端统一返回 401 Unauthorized 响应:
HTTP/1.1 401 Unauthorized
Unauthorized: Invalid or missing authentication token
2. 数据结构与类型定义 (Rust & TypeScript Schema)
2.1 6维网格点参数 (GridPointParams)
定义恒星大气模型的 6 维大气参数:温度 $T_{\text{eff}}$、重力加速度 $\log g$、以及元素丰度 \log(N_{\text{He}}/N_{\text{H}}), \log(N_{\text{C}}/N_{\text{H}}), \log(N_{\text{N}}/N_{\text{H}}), $\log(N_{\text{O}}/N_{\text{H}})$。
-
Rust 定义 (models.rs):
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct GridPointParams { pub teff: f64, // 有效温度 (K), e.g. 35000.0 pub logg: f64, // 表面重力加速度对数 (cgs), e.g. 5.5 pub loghe: f64, // 氦丰度对数, e.g. -1.0 pub logc: f64, // 碳丰度对数, e.g. -2.0 pub logn: f64, // 氮丰度对数, e.g. -2.0 pub logo: f64, // 氧丰度对数, e.g. -2.0 } -
TypeScript 类型声明:
export interface GridPointParams { teff: number; logg: number; loghe: number; logc: number; logn: number; logo: number; }
2.2 任务规格 (TaskSpec)
服务端派发给 Worker 节点的单个计算任务定义。
-
Rust 定义 (models.rs):
#[derive(Debug, Clone, Serialize, Deserialize)] pub struct TaskSpec { pub task_id: Uuid, pub point_name: String, pub params: GridPointParams, pub task_type: TaskType, // ColdRun | SeedStep pub seed_point_name: Option<String>,// 步进种子点名称(如适用) pub timeout_sec: u64, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum TaskType { ColdRun, SeedStep, } -
TypeScript 类型声明:
export type TaskType = 'cold_run' | 'seed_step'; export interface TaskSpec { task_id: string; point_name: string; params: GridPointParams; task_type: TaskType; seed_point_name?: string | null; timeout_sec: number; }
2.3 任务上报报告 (TaskReport)
Worker 节点向服务端上报的任务计算结果。
-
Rust 定义 (models.rs):
#[derive(Debug, Clone, Serialize, Deserialize)] pub struct TaskReport { pub task_id: Uuid, pub point_name: String, #[serde(default)] pub params: Option<GridPointParams>, pub node_id: String, pub status: TaskStatus, // Pending | Running | Completed | Failed | Timeout pub converged: bool, pub max_relc: Option<f64>, pub atmosphere_has_nan: bool, pub elapsed_sec: f64, pub error_message: Option<String>, pub summary_json: String, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum TaskStatus { Pending, Running, Completed, Failed, Timeout, } -
TypeScript 类型声明:
export type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'timeout'; export interface TaskReport { task_id: string; point_name: string; params?: GridPointParams; node_id: string; status: TaskStatus; converged: boolean; max_relc?: number | null; atmosphere_has_nan: boolean; elapsed_sec: number; error_message?: string | null; summary_json: string; }
2.4 节点信息与请求模型 (NodeRegisterRequest / NodeHeartbeatRequest)
-
Rust 定义 (models.rs):
pub struct NodeRegisterRequest { pub node_id: String, pub host_name: String, pub max_slots: i32, } pub struct NodeHeartbeatRequest { pub node_id: String, pub active_slots: i32, pub cpu_usage: f32, pub memory_usage: f32, } pub struct NodeInfo { pub node_id: String, pub host_name: String, pub max_slots: i32, pub active_slots: i32, pub status: String, pub cpu_usage: f32, pub memory_usage: f32, pub last_heartbeat: DateTime<Utc>, } -
TypeScript 类型声明:
export interface NodeRegisterRequest { node_id: string; host_name: string; max_slots: number; } export interface NodeHeartbeatRequest { node_id: string; active_slots: number; cpu_usage: number; memory_usage: number; } export interface NodeInfo { node_id: string; host_name: string; max_slots: number; active_slots: number; status: 'online' | 'offline'; cpu_usage: number; memory_usage: number; last_heartbeat: string; }
2.5 工作流响应模型与请求体 (CreateWorkflowRequest / ApiResponse<T>)
-
Rust 定义 (workflow.rs):
pub struct CreateWorkflowRequest { pub name: String, pub description: Option<String>, pub config_yaml: String, } pub struct ApiResponse<T> { pub success: bool, pub message: String, pub data: Option<T>, } -
TypeScript 类型声明:
export interface CreateWorkflowRequest { name: string; description?: string | null; config_yaml: string; } export interface ApiResponse<T = unknown> { success: boolean; message: string; data?: T | null; } export interface WorkflowSummary { name: string; description?: string | null; status: 'idle' | 'running' | 'paused' | 'completed'; created_at: string; updated_at: string; } export interface WorkflowItem { name: string; description?: string | null; config_yaml: string; status: 'idle' | 'running' | 'paused' | 'completed'; created_at: string; updated_at: string; }
3. 计算节点管理 API (Node Management)
处理 Worker 节点的注册登录与定期心跳保活。
3.1 注册计算节点 (POST /api/node/register)
- 处理函数:
register_node - 函数签名:
pub async fn register_node( State(state): State<AppState>, Json(req): Json<NodeRegisterRequest>, ) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 请求 Header:
Content-Type: application/json - 请求 Body:
{ "node_id": "node-worker-01", "host_name": "hpc-node-01.local", "max_slots": 8 } - 响应 Schema:
200 OK(成功):{ "status": "ok", "message": "节点注册成功" }200 OK(数据库异常):{ "status": "error", "message": "数据库错误详情" }
- curl 示例:
curl -X POST http://localhost:8090/api/node/register \ -H "Content-Type: application/json" \ -H "Authorization: Bearer secret_token" \ -d '{ "node_id": "node-worker-01", "host_name": "hpc-node-01.local", "max_slots": 8 }'
3.2 节点心跳保活 (POST /api/node/heartbeat)
- 处理函数:
heartbeat_node - 函数签名:
pub async fn heartbeat_node( State(state): State<AppState>, Json(req): Json<NodeHeartbeatRequest>, ) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 请求 Header:
Content-Type: application/json - 请求 Body:
{ "node_id": "node-worker-01", "active_slots": 2, "cpu_usage": 45.2, "memory_usage": 30.8 } - 响应 Schema:
200 OK(成功):{ "status": "ok" }200 OK(失败):{ "status": "error", "message": "节点未找到或心跳更新失败" }
- curl 示例:
curl -X POST http://localhost:8090/api/node/heartbeat \ -H "Content-Type: application/json" \ -H "Authorization: Bearer secret_token" \ -d '{ "node_id": "node-worker-01", "active_slots": 2, "cpu_usage": 45.2, "memory_usage": 30.8 }'
4. 任务调度与结果上报 API (Task Processing)
支持 Worker 节点抢占式领用任务与计算结果(含种子 .7 文件)上传。
4.1 领用计算任务 (POST /api/task/claim)
- 处理函数:
claim_task - 函数签名:
pub async fn claim_task(State(state): State<AppState>) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 请求 Body: 无
- 响应 Schema:
200 OK(有可计算任务):{ "status": "ok", "task": { "task_id": "550e8400-e29b-41d4-a716-446655440000", "point_name": "t35000_g5.5_he-1_c-2_n-2_o-2", "params": { "teff": 35000.0, "logg": 5.5, "loghe": -1.0, "logc": -2.0, "logn": -2.0, "logo": -2.0 }, "task_type": "cold_run", "seed_point_name": null, "timeout_sec": 7200 } }200 OK(当前队列为空):{ "status": "empty", "task": null }500 Internal Server Error:{ "status": "error", "message": "领用任务失败: <error_details>" }
- curl 示例:
curl -X POST http://localhost:8090/api/task/claim \ -H "Authorization: Bearer secret_token"
4.2 上报任务结果与种子文件 (POST /api/task/report)
- 处理函数:
report_task - 函数签名:
pub async fn report_task( State(state): State<AppState>, mut multipart: Multipart, ) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 请求格式:
multipart/form-data- Part
report: JSON 字符串 (映射为TaskReport) - Part
seed_file(可选): 二进制数据 (收敛网格点的.7大气结构种子文件)
- Part
- 响应 Schema:
200 OK(成功):{ "status": "ok", "message": "上报成功" }400 Bad Request(缺少report字段):{ "status": "error", "message": "请求中缺少 report 字段" }400 Bad Request(参数格式错误):{ "status": "error", "message": "无法解析 params 或 summary_json" }
- 说明: 当
converged == true且atmosphere_has_nan == false且包含seed_file时,服务端会将种子保存至results_dir/<point_name>/<point_name>.7并记入seeds表。若冷启动任务失败,服务端会自动唤醒GridScheduler触发针对该网格点的步进回退算法 (Seed-step Fallback)。 - curl 示例:
curl -X POST http://localhost:8090/api/task/report \ -H "Authorization: Bearer secret_token" \ -F 'report={ "task_id": "550e8400-e29b-41d4-a716-446655440000", "point_name": "t35000_g5.5_he-1_c-2_n-2_o-2", "node_id": "node-worker-01", "status": "completed", "converged": true, "max_relc": 0.00008, "atmosphere_has_nan": false, "elapsed_sec": 142.5, "error_message": null, "summary_json": "{\"name\":\"t35000_g5.5_he-1_c-2_n-2_o-2\",\"params\":{\"teff\":35000.0,\"logg\":5.5,\"loghe\":-1.0,\"logc\":-2.0,\"logn\":-2.0,\"logo\":-2.0},\"stages\":[],\"converged\":true,\"elapsed_sec\":142.5,\"atmosphere_has_nan\":false}" };type=application/json' \ -F 'seed_file=@/path/to/t35000_g5.5_he-1_c-2_n-2_o-2.7'
5. 种子文件管理 API (Seed Management)
提供在网格计算过程中相近网格点间传递与下载 TLUSTY fort.7 大气结构二进制种子文件的功能。
5.1 下载网格点种子文件 (GET /api/seed/:name)
- 处理函数:
download_seed - 函数签名:
pub async fn download_seed( State(state): State<AppState>, AxumPath(name): AxumPath<String>, ) -> Response - 鉴权: 是 (若配置 Token)
- 路径参数:
name: 网格点名称 (例如:t35000_g5.5_he-1_c-2_n-2_o-2)
- 安全检查: 防止路径穿越攻击,校验参数中不可包含
..、/或\。 - 响应 Header:
Content-Type: application/octet-streamContent-Disposition: attachment; filename="<name>.7"
- 状态码与响应体:
200 OK: 返回文件二进制流400 Bad Request:"非法的种子名称参数"404 Not Found:"请求的种子文件不存在"500 Internal Server Error:"无法打开种子文件"
- curl 示例:
curl -X GET http://localhost:8090/api/seed/t35000_g5.5_he-1_c-2_n-2_o-2 \ -H "Authorization: Bearer secret_token" \ --output t35000_g5.5_he-1_c-2_n-2_o-2.7
6. 静态资源与数据下载 API (Data Assets)
供 Worker 节点下载执行 TLUSTY / SYNSPEC 所需的原子数据文件和线表。
6.1 下载任意数据资源文件 (GET /api/data/file/*filename)
- 处理函数:
download_single_data_file - 函数签名:
pub async fn download_single_data_file( AxumPath(filename): AxumPath<String> ) -> axum::response::Response - 鉴权: 是 (若配置 Token)
- 路径参数:
filename: 文件相对名称 (例如:he2.dat)
- 响应 Header:
Content-Type: application/octet-streamContent-Disposition: attachment; filename="<filename>"
- 状态码与响应体:
200 OK: 返回数据文件二进制流400 Bad Request:"无效的数据文件名"404 Not Found:"资源数据文件不存在"500 Internal Server Error:"无法读取资源数据文件"
- curl 示例:
curl -X GET http://localhost:8090/api/data/file/he2.dat \ -H "Authorization: Bearer secret_token" \ --output he2.dat
6.2 下载主光谱线表文件 (GET /api/data/linelist)
- 处理函数:
download_linelist - 函数签名:
pub async fn download_linelist() -> axum::response::Response - 鉴权: 是 (若配置 Token)
- 响应: 默认定位并流式返回
assets/gfVIS99.dat文件。 - 状态码:
200 OK(或404 Not Found/500 Internal Server Error) - curl 示例:
curl -X GET http://localhost:8090/api/data/linelist \ -H "Authorization: Bearer secret_token" \ --output gfVIS99.dat
7. 系统状态监控 API (System Status)
实时监控分布式计算集群节点活跃度与计算槽位利用率。
7.1 获取集群整体状态 (GET /api/status)
- 处理函数:
get_status - 函数签名:
pub async fn get_status(State(state): State<AppState>) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 响应 Schema (
200 OK):{ "status": "online", "nodes_online": 2, "total_active_slots": 4, "total_max_slots": 16, "nodes": [ { "node_id": "node-worker-01", "host_name": "hpc-node-01.local", "max_slots": 8, "active_slots": 2, "status": "online", "cpu_usage": 45.2, "memory_usage": 30.8, "last_heartbeat": "2026-07-27T16:55:00.000Z" } ], "grid_stats": { "total": 512, "pending": 210, "running": 32, "converged": 260, "failed": 10 } } - curl 示例:
curl -X GET http://localhost:8090/api/status \ -H "Authorization: Bearer secret_token"
8. 工作流管理 API (Workflow CRUD & Execution)
管理恒星大气网格计算工作流 YAML 配置的增删改查、启动与暂停控制。
8.1 获取工作流列表 (GET /api/workflows)
- 处理函数:
list_workflows - 函数签名:
pub async fn list_workflows(State(state): State<AppState>) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 说明: 返回工作流轻量级元数据列表(包含
name、description、status、created_at、updated_at)。如需获取具体工作流的 YAML 配置详情,请调用GET /api/workflows/:name。 - 响应 Schema (
200 OK):{ "success": true, "message": "成功获取工作流列表", "data": [ { "name": "sdB_cno", "description": "sdB CNO 6D Stellar Atmosphere Grid", "status": "idle", "created_at": "2026-07-27T08:00:00Z", "updated_at": "2026-07-27T08:00:00Z" } ] } - curl 示例:
curl -X GET http://localhost:8090/api/workflows \ -H "Authorization: Bearer secret_token"
8.2 创建或保存工作流 (POST /api/workflows / PUT /api/workflows/:name)
- 处理函数:
save_workflow - 函数签名:
pub async fn save_workflow( State(state): State<AppState>, Json(req): Json<CreateWorkflowRequest>, ) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 请求 Body:
{ "name": "sdB_cno_custom", "description": "自定义 6维 网格计算工作流", "config_yaml": "grid:\n teff: [35000, 36000]\n logg: [5.5, 6.0]\n loghe: [-1.0]\n logc: [-2.0]\n logn: [-2.0]\n logo: [-2.0]\nchain:\n - label: LTE_START\n lte: T\n niter: 30\n" } - 响应 Schema:
200 OK(成功保存):{ "success": true, "message": "工作流 'sdB_cno_custom' 保存成功", "data": null }400 Bad Request(YAML 格式不合法):{ "success": false, "message": "无效的 YAML 配置: invalid syntax at line 2...", "data": null }
- curl 示例:
curl -X POST http://localhost:8090/api/workflows \ -H "Content-Type: application/json" \ -H "Authorization: Bearer secret_token" \ -d '{ "name": "sdB_cno_custom", "description": "自定义 6维 网格计算工作流", "config_yaml": "grid:\n teff: [35000, 36000]\n logg: [5.5, 6.0]\n loghe: [-1.0]\n logc: [-2.0]\n logn: [-2.0]\n logo: [-2.0]\nchain:\n - label: LTE_START\n lte: T\n niter: 30\n" }'
8.3 获取特定工作流详情 (GET /api/workflows/:name)
- 处理函数:
get_workflow - 函数签名:
pub async fn get_workflow( State(state): State<AppState>, AxumPath(name): AxumPath<String>, ) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 路径参数:
name(工作流唯一名称,如sdB_cno) - 响应 Schema:
200 OK(成功):{ "success": true, "message": "成功获取工作流详情", "data": { "id": 1, "name": "sdB_cno", "description": "sdB CNO 6D Stellar Atmosphere Grid", "config_yaml": "...", "status": "idle", "created_at": "2026-07-27T08:00:00Z", "updated_at": "2026-07-27T08:00:00Z" } }404 Not Found(不存在):{ "success": false, "message": "工作流 'unknown_wf' 未找到", "data": null }
- curl 示例:
curl -X GET http://localhost:8090/api/workflows/sdB_cno \ -H "Authorization: Bearer secret_token"
8.4 删除工作流 (DELETE /api/workflows/:name)
- 处理函数:
delete_workflow - 函数签名:
pub async fn delete_workflow( State(state): State<AppState>, AxumPath(name): AxumPath<String>, ) -> impl IntoResponse - 鉴权: 是 (若配置 Token)
- 响应 Schema (
200 OK):{ "success": true, "message": "工作流 'sdB_cno_custom' 已删除", "data": null } - curl 示例:
curl -X DELETE http://localhost:8090/api/workflows/sdB_cno_custom \ -H "Authorization: Bearer secret_token"
8.5 启动工作流 (POST /api/workflows/:name/start)
- 处理函数:
start_workflow - 函数签名:
pub async fn start_workflow( State(state): State<AppState>, AxumPath(name): AxumPath<String>, ) -> impl IntoResponse - 说明: 校验工作流,解析 YAML 中定义的所有 6 维网格坐标点,通过
GridScheduler::initialize_grid展开网格点并计算保序难度 Wave,写入 SQLite 任务队列并开启节点调度。 - 响应 Schema:
200 OK(成功启动):{ "success": true, "message": "工作流 'sdB_cno' 已成功启动并安排计算任务", "data": null }400 Bad Request(重复启动):{ "success": false, "message": "工作流 'sdB_cno' 已处于运行状态,无需重复启动", "data": null }404 Not Found:{ "success": false, "message": "工作流 'sdB_cno' 未找到", "data": null }
- curl 示例:
curl -X POST http://localhost:8090/api/workflows/sdB_cno/start \ -H "Authorization: Bearer secret_token"
8.6 暂停工作流 (POST /api/workflows/:name/stop)
- 处理函数:
stop_workflow - 函数签名:
pub async fn stop_workflow( State(state): State<AppState>, AxumPath(name): AxumPath<String>, ) -> impl IntoResponse - 响应 Schema (
200 OK):{ "success": true, "message": "工作流 'sdB_cno' 已暂停", "data": null } - curl 示例:
curl -X POST http://localhost:8090/api/workflows/sdB_cno/stop \ -H "Authorization: Bearer secret_token"
9. 错误处理与状态码汇总
| HTTP 状态码 | 触发场景说明 | 响应格式 | 核心原因与解决建议 |
|---|---|---|---|
200 OK |
请求正常处理 | JSON / Binary Stream | 操作成功执行。 |
400 Bad Request |
参数校验失败、缺失关键字段或 YAML 格式错误 | application/json / Plain Text |
检查请求 JSON 结构,验证 YAML 配置语法是否正确。 |
401 Unauthorized |
鉴权失败或缺失 Authorization Header | Plain Text | 确认环境变量 DCTS_AUTH_TOKEN 配置,并在 Request Header 中包含正确的 Bearer <token> 或 x-api-key。 |
404 Not Found |
资源、种子文件或工作流不存在 | application/json / Plain Text |
校验请求 URL 中的资源文件名或工作流 name 是否拼写无误。 |
500 Internal Server Error |
服务端数据库错误、I/O 打开失败或队列异常 | application/json / Plain Text |
检查服务端日志以进一步厘清 SQLite 锁冲突、磁盘空间或资源路径问题。 |
文档生成于 2026-07-27 | DCTS Server 0.1.0