合并 origin/master
合入 master 的钱包退款 outbox、拼图后台编译互斥与公开链路更新 保留当前分支外部生成 worker 队列语义,并对齐拼图首图 claim 释放顺序
This commit is contained in:
@@ -588,7 +588,7 @@ pub async fn execute_puzzle_agent_action(
|
||||
let owner_user_id = authenticated.claims().user_id().to_string();
|
||||
let now = current_utc_micros();
|
||||
let action = payload.action.trim().to_string();
|
||||
let billing_asset_id = format!("{session_id}:{now}");
|
||||
let billing_asset_id = format!("{}:{}:{}", session_id, action, request_context.request_id());
|
||||
tracing::info!(
|
||||
provider = PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
session_id = %session_id,
|
||||
@@ -658,6 +658,79 @@ pub async fn execute_puzzle_agent_action(
|
||||
reference_image_src: primary_reference_image_src.map(ToOwned::to_owned),
|
||||
image_model: payload.image_model.clone(),
|
||||
requested_at_micros: now,
|
||||
background_task_id: None,
|
||||
background_claim_id: None,
|
||||
};
|
||||
let worker_payload = if ai_redraw {
|
||||
let background_task_id =
|
||||
build_puzzle_background_compile_task_id(&compile_session_id);
|
||||
let background_claim_id = build_puzzle_background_compile_claim_id(
|
||||
&background_task_id,
|
||||
request_context.request_id(),
|
||||
);
|
||||
let claim_result = state
|
||||
.spacetime_client()
|
||||
.claim_puzzle_background_compile_task(
|
||||
PuzzleBackgroundCompileTaskClaimRecordInput {
|
||||
task_id: background_task_id.clone(),
|
||||
claim_id: background_claim_id.clone(),
|
||||
session_id: compile_session_id.clone(),
|
||||
owner_user_id: owner_user_id.clone(),
|
||||
claimed_at_micros: current_utc_micros(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
puzzle_error_response(
|
||||
&request_context,
|
||||
PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
map_puzzle_client_error(error),
|
||||
)
|
||||
})?;
|
||||
if !claim_result {
|
||||
tracing::info!(
|
||||
provider = PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
session_id = %compile_session_id,
|
||||
owner_user_id = %owner_user_id,
|
||||
task_id = %background_task_id,
|
||||
"拼图首图后台生成任务已存在,本次 action 直接返回生成中会话"
|
||||
);
|
||||
let session = state
|
||||
.spacetime_client()
|
||||
.get_puzzle_agent_session(compile_session_id.clone(), owner_user_id.clone())
|
||||
.await
|
||||
.map(mark_puzzle_initial_generation_started_snapshot)
|
||||
.map_err(|error| {
|
||||
puzzle_error_response(
|
||||
&request_context,
|
||||
PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
map_puzzle_client_error(error),
|
||||
)
|
||||
})?;
|
||||
return Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
PuzzleAgentActionResponse {
|
||||
operation: PuzzleAgentOperationResponse {
|
||||
operation_id: background_task_id,
|
||||
operation_type: "compile_puzzle_draft".to_string(),
|
||||
status: "running".to_string(),
|
||||
phase_label: "首关拼图草稿".to_string(),
|
||||
phase_detail: "首关草稿生成已在后台处理中。".to_string(),
|
||||
progress: session.progress_percent.max(10),
|
||||
error: None,
|
||||
},
|
||||
session: map_puzzle_agent_session_response(session),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
PuzzleCompileDraftWorkerPayload {
|
||||
background_task_id: Some(background_task_id),
|
||||
background_claim_id: Some(background_claim_id),
|
||||
..worker_payload
|
||||
}
|
||||
} else {
|
||||
worker_payload
|
||||
};
|
||||
if state
|
||||
.root_state()
|
||||
@@ -675,7 +748,7 @@ pub async fn execute_puzzle_agent_action(
|
||||
let session = execute_puzzle_compile_draft_worker_job(
|
||||
&state,
|
||||
&request_context,
|
||||
worker_payload,
|
||||
worker_payload.clone(),
|
||||
ExternalGenerationWriteLeaseGuard::inline(),
|
||||
)
|
||||
.await
|
||||
@@ -707,6 +780,18 @@ pub async fn execute_puzzle_agent_action(
|
||||
));
|
||||
}
|
||||
let request_payload_json = serde_json::to_string(&worker_payload).map_err(|error| {
|
||||
if let (Some(task_id), Some(claim_id)) = (
|
||||
worker_payload.background_task_id.as_deref(),
|
||||
worker_payload.background_claim_id.as_deref(),
|
||||
) {
|
||||
spawn_release_claimed_puzzle_background_compile_task(
|
||||
state.clone(),
|
||||
task_id.to_string(),
|
||||
claim_id.to_string(),
|
||||
compile_session_id.clone(),
|
||||
owner_user_id.clone(),
|
||||
);
|
||||
}
|
||||
puzzle_error_response(
|
||||
&request_context,
|
||||
PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
@@ -736,6 +821,18 @@ pub async fn execute_puzzle_agent_action(
|
||||
})
|
||||
.await
|
||||
.map_err(|error| {
|
||||
if let (Some(task_id), Some(claim_id)) = (
|
||||
worker_payload.background_task_id.as_deref(),
|
||||
worker_payload.background_claim_id.as_deref(),
|
||||
) {
|
||||
spawn_release_claimed_puzzle_background_compile_task(
|
||||
state.clone(),
|
||||
task_id.to_string(),
|
||||
claim_id.to_string(),
|
||||
compile_session_id.clone(),
|
||||
owner_user_id.clone(),
|
||||
);
|
||||
}
|
||||
puzzle_error_response(
|
||||
&request_context,
|
||||
PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
@@ -2034,7 +2131,7 @@ pub async fn use_puzzle_runtime_prop(
|
||||
}
|
||||
};
|
||||
let should_sync_freeze_boundary = matches!(prop_kind.as_str(), "freezeTime" | "freeze_time");
|
||||
let billing_asset_id = format!("{}:{}:{}", run_id, prop_kind, current_utc_micros());
|
||||
let billing_asset_id = format!("{}:{}:{}", run_id, prop_kind, request_context.request_id());
|
||||
let reducer_owner_user_id = owner_user_id.clone();
|
||||
let reducer_run_id = run_id.clone();
|
||||
let fallback_run_id = run_id.clone();
|
||||
|
||||
Reference in New Issue
Block a user