扩展外部生成Worker队列
新增外部生成队列概览和单任务状态契约 将跳一跳、拼消消、敲木鱼图片生成动作接入worker队列 前端生成等待页展示当前任务和队列数量 更新外部生成worker运维文档和团队决策记录
This commit is contained in:
108
server-rs/crates/api-server/src/external_generation.rs
Normal file
108
server-rs/crates/api-server/src/external_generation.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Extension, Path, State},
|
||||
http::StatusCode,
|
||||
response::Response,
|
||||
};
|
||||
use serde_json::json;
|
||||
use shared_contracts::external_generation::{
|
||||
ExternalGenerationJobStatus, ExternalGenerationJobStatusRecord,
|
||||
ExternalGenerationJobStatusResponse, ExternalGenerationQueueOverview,
|
||||
ExternalGenerationQueueOverviewResponse,
|
||||
};
|
||||
use spacetime_client::{
|
||||
ExternalGenerationJobGetRecordInput, ExternalGenerationJobRecord,
|
||||
ExternalGenerationQueueStatsRecord, SpacetimeClientError,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
api_response::json_success_body, auth::AuthenticatedAccessToken, http_error::AppError,
|
||||
request_context::RequestContext, state::AppState,
|
||||
};
|
||||
|
||||
const EXTERNAL_GENERATION_PROVIDER: &str = "external_generation";
|
||||
|
||||
pub async fn get_external_generation_queue_overview(
|
||||
State(state): State<AppState>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
) -> Result<Json<serde_json::Value>, Response> {
|
||||
let stats = state
|
||||
.spacetime_client()
|
||||
.get_external_generation_queue_stats()
|
||||
.await
|
||||
.map_err(|error| external_generation_error_response(&request_context, error))?;
|
||||
|
||||
Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
ExternalGenerationQueueOverviewResponse {
|
||||
overview: map_external_generation_queue_overview(stats),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn get_external_generation_job_status(
|
||||
State(state): State<AppState>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
Path(job_id): Path<String>,
|
||||
) -> Result<Json<serde_json::Value>, Response> {
|
||||
let owner_user_id = authenticated.claims().user_id().to_string();
|
||||
let job = state
|
||||
.spacetime_client()
|
||||
.get_external_generation_job(ExternalGenerationJobGetRecordInput {
|
||||
job_id,
|
||||
owner_user_id,
|
||||
})
|
||||
.await
|
||||
.map_err(|error| external_generation_error_response(&request_context, error))?;
|
||||
|
||||
Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
ExternalGenerationJobStatusResponse {
|
||||
job: map_external_generation_job_status(job),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn map_external_generation_queue_overview(
|
||||
stats: ExternalGenerationQueueStatsRecord,
|
||||
) -> ExternalGenerationQueueOverview {
|
||||
ExternalGenerationQueueOverview {
|
||||
pending_count: stats.pending_count,
|
||||
running_count: stats.running_active_count,
|
||||
updated_at_micros: stats.now_micros,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_external_generation_job_status(
|
||||
job: ExternalGenerationJobRecord,
|
||||
) -> ExternalGenerationJobStatusRecord {
|
||||
let (status, phase_detail, progress) = match job.status.as_str() {
|
||||
"completed" => (ExternalGenerationJobStatus::Completed, "生成已完成。", 100),
|
||||
"running" => (ExternalGenerationJobStatus::Running, "正在生成。", 35),
|
||||
"failed" => (ExternalGenerationJobStatus::Failed, "生成失败。", 0),
|
||||
_ => (ExternalGenerationJobStatus::Queued, "排队中。", 8),
|
||||
};
|
||||
|
||||
ExternalGenerationJobStatusRecord {
|
||||
operation_id: job.job_id,
|
||||
status,
|
||||
phase_label: job.request_label,
|
||||
phase_detail: phase_detail.to_string(),
|
||||
progress,
|
||||
error: job.last_error_message,
|
||||
updated_at_micros: job.updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
fn external_generation_error_response(
|
||||
request_context: &RequestContext,
|
||||
error: SpacetimeClientError,
|
||||
) -> Response {
|
||||
AppError::from_status(StatusCode::BAD_GATEWAY)
|
||||
.with_details(json!({
|
||||
"provider": EXTERNAL_GENERATION_PROVIDER,
|
||||
"message": error.to_string(),
|
||||
}))
|
||||
.into_response_with_context(Some(request_context))
|
||||
}
|
||||
Reference in New Issue
Block a user