Prhub

#44499 [Rust Frontend] Add /pause, /resume, /is_paused endpoints

原始 PR 作者 sahilsGit 合并时间 2026-06-08 17:28 文件变更 4 提交数 2 评论 3 代码增减 +284 / -0

执行摘要

为 Rust 前端添加暂停 / 恢复 / 状态查询端点

为 Rust 前端贡献 RL / admin / lifecycle APIs(参见路线图 #44280),提供与 Python frontend 等价的生命周期管理能力,支持权重更新等场景下的调度器暂停/恢复。

值得精读,特别是 is_scheduler_paused 的跨引擎一致性检查实现和测试中 mock engine 的模式,对于开发类似 admin 端点的开发者有参考价值。

讨论亮点

Review 中仅有一条 BugenZhao 的 "LGTM" 批准评论,无其他实质性讨论。整体实现直白,与现有 sleep/wake 端点模式一致。

实现拆解

  1. rust/src/engine-core-client/src/client.rs 中新增三个方法:pause_scheduler(mode, clear_cache) 通过 call_utility 调用引擎的 pause_schedulerresume_scheduler() 调用 resume_scheduleris_scheduler_paused() 调用 is_scheduler_paused 并实现跨引擎一致性检查。

  2. 新建 rust/src/server/src/routes/pause.rs,定义 PauseParams 结构体(含 modeclear_cache 参数,默认值分别为 "abort"true),实现 pauseresumeis_paused 三个异步处理器,均通过 AppState 获取引擎客户端并调用相应方法,返回 JSON 响应。

  3. rust/src/server/src/routes.rs 的 dev-mode 路由块中注册三条新路由:/pause (POST)、/resume (POST)、/is_paused (GET),并引入 mod pause

  4. rust/src/server/src/routes/tests.rs 中添加四个集成测试:验证默认参数向后兼容性、非法 mode 返回 400、resume 发送空参数、is_paused 返回正确 JSON 负载;并扩展 admin_routes_are_hidden_when_dev_mode_is_disabled 测试确认新端点被隐藏。

文件 模块 状态 重要度
rust/src/server/src/routes/pause.rs 服务路由 added 8.54
rust/src/server/src/routes/tests.rs 服务路由 modified 8.3
rust/src/engine-core-client/src/client.rs 引擎客户端 modified 7.64
rust/src/server/src/routes.rs 服务路由 modified 4.1

关键符号

pause resume is_paused pause_scheduler resume_scheduler is_scheduler_paused

关键源码片段

rust/src/server/src/routes/pause.rs entrypoint

新增文件,实现三个端点核心逻辑,包括参数解析、校验、引擎调用和响应构造。

// 文件 : rust/src/server/src/routes/pause.rs
// 实现 /pause, /resume, /is_paused 三个管理端点use std::sync::Arc;
use axum::{Json, extract::{Query, State}};
use serde::{Deserialize, Serialize};
use crate::{error::ApiError, state::AppState, utils::utility_call_error};/// 查询参数:`mode` 默认 "abort",`clear_cache` 默认 true
#[derive(Debug, Deserialize)]
pub(crate) struct PauseParams {
    #[serde(default = "default_pause_mode")]
    mode: String,
    #[serde(default = "default_clear_cache")]
    clear_cache: bool,
}/// 统一响应结构
#[derive(Serialize)]
pub(crate) struct StatusResponse {
    status: &'static str,
}/// /is_paused 响应
#[derive(Serialize)]
pub(crate) struct IsPausedResponse {
    is_paused: bool,
}/// 合法的 pause mode,对应 Python 端的 `PauseMode`
const VALID_PAUSE_MODES: [&str; 3] = ["abort", "wait", "keep"];fn default_pause_mode() -> String {
    "abort".to_string()
}const fn default_clear_cache() -> bool {
    true
}// TODO: Python 端还接受已废弃的 `wait_for_inflight_requests` 参数,
// 此处未实现,统一使用 `mode` 参数/// 暂停调度器,用于停止生成(如进行权重更新)
pub async fn pause(
    State(state): State<Arc<AppState>>,
    Query(params): Query<PauseParams>,
) -> Result<Json<StatusResponse>, ApiError> {
    // 校验 mode 参数,无效则返回 400
    if !VALID_PAUSE_MODES.contains(&params.mode.as_str()) {
        return Err(ApiError::invalid_request(
            format!("Invalid pause mode '{}'; expected one of: abort, wait, keep", params.mode),
            Some("mode"),
        ));
    }
    // 通过 engine_core_client 调用引擎端的 pause_scheduler
    state.engine_core_client()
        .pause_scheduler(&params.mode, params.clear_cache)
        .await
        .map_err(|error| utility_call_error("pause", error))?;
    Ok(Json(StatusResponse { status: "paused" }))
}/// 恢复调度器运行
pub async fn resume(
    State(state): State<Arc<AppState>>,
) -> Result<Json<StatusResponse>, ApiError> {
    state.engine_core_client()
        .resume_scheduler()
        .await
        .map_err(|error| utility_call_error("resume", error))?;
    Ok(Json(StatusResponse { status: "resumed" }))
}/// 查询调度器是否处于暂停状态
pub async fn is_paused(
    State(state): State<Arc<AppState>>,
) -> Result<Json<IsPausedResponse>, ApiError> {
    let is_paused = state.engine_core_client()
        .is_scheduler_paused()
        .await
        .map_err(|error| utility_call_error("is_paused", error))?;
    Ok(Json(IsPausedResponse { is_paused }))
}
rust/src/engine-core-client/src/client.rs core-logic

核心客户端扩展,新增 pause_scheduler、resume_scheduler、is_scheduler_paused 三个方法,其中 is_scheduler_paused 实现了跨引擎一致性检查。

// 文件 : rust/src/engine-core-client/src/client.rs ( 新增方法片段 )
// 注意:这些方法位于 impl EngineCoreClient 块中/// 暂停调度器,参数由 Python 前端定义
pub async fn pause_scheduler(&self, mode: &str, clear_cache: bool) -> Result<()> {
    // 调用引擎端注册的 utility 方法 "pause_scheduler"
    self.call_utility::<(), _>("pause_scheduler", (mode, clear_cache)).await?;
    Ok(())
}/// 恢复调度器(无参数)
pub async fn resume_scheduler(&self) -> Result<()> {
    self.call_utility::<(), _>("resume_scheduler", ()).await?;
    Ok(())
}/// 查询调度器是否暂停,跨引擎一致性检查
pub async fn is_scheduler_paused(&self) -> Result<bool> {
    // 从所有引擎收集结果
    let results: Vec<bool> = self.call_utility("is_scheduler_paused", ()).await?;
    // 确保 results 非空(启动时保证 engine_count >= 1)
    let first = *results.first().ok_or_else(|| Error::InconsistentUtilityResults {
        method: "is_scheduler_paused".to_string(),
        values: "[]".to_string(),
    })?;
    // 所有引擎结果必须一致,否则报错
    if results.iter().all(|&v| v == first) {
        Ok(first)
    } else {
        Err(Error::InconsistentUtilityResults {
            method: "is_scheduler_paused".to_string(),
            values: format!("{results:?}"),
        })
    }
}

评论区精华

PR 审查 other

BugenZhao 审查后回复 'LGTM' 并批准,未发起任何讨论。

结论:批准合并 · 已解决

风险与影响

风险较低:新端点仅在 dev-mode 启用,不影响生产路径;is_scheduler_paused 的跨引擎一致性检查可能因多引擎状态不一致而报错,但这是有意设计;如果后端引擎未实现对应 pause_scheduler 等 utility 方法,调用会失败并返回清晰错误。主要的潜在风险是新增 utility 方法名与 Python 端不一致,但已采用相同的字符串标识,保证兼容。

对用户:提供通过 Rust 前端管理调度器暂停/恢复的能力,便于集成到自动化运维流程。对系统:增加少量代码和路由注册,无性能影响。对团队:展示了 Rust 前端中 admin 端点的标准实现模式,便于后续添加类似端点(如重置缓存等)参考。

仅 dev-mode 暴露 跨引擎一致性检查 依赖后端 engine utility 实现

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论