fix: 修复任务状态同步问题 - 连续失败时标记任务为失败

问题修复:
- API查询失败时只打印警告,没有更新数据库状态
- 前端显示运行中,但后端日志显示连续失败
- 任务会一直轮询直到超时,用户体验差

技术实现:
- 添加连续失败计数器 (consecutive_failures)
- 连续失败3次后自动标记任务为失败状态
- 立即更新数据库记录,前端能及时看到失败状态
- 避免无意义的长时间轮询

修复逻辑:
- 成功时重置失败计数器
- 失败时增加计数器
- 达到上限时标记为失败并退出轮询
- 错误类型: API_CONSECUTIVE_FAILURES

用户体验改进:
- 快速反馈任务失败状态(30秒内)
- 避免长时间显示运行中的假象
- 明确的失败原因和错误代码
This commit is contained in:
imeepos 2025-07-31 13:17:55 +08:00
parent 65412e80b7
commit 1a504fa4b0
1 changed files with 19 additions and 0 deletions

View File

@ -307,6 +307,8 @@ impl VolcanoVideoService {
let mut attempts = 0; let mut attempts = 0;
let max_attempts = 60; // 最多轮询60次约10分钟 let max_attempts = 60; // 最多轮询60次约10分钟
let mut consecutive_failures = 0;
let max_consecutive_failures = 3; // 连续失败3次就标记为失败
while attempts < max_attempts { while attempts < max_attempts {
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await; tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
@ -314,6 +316,8 @@ impl VolcanoVideoService {
match self.check_task_status(&task_id).await { match self.check_task_status(&task_id).await {
Ok(status_response) => { Ok(status_response) => {
// 重置连续失败计数器
consecutive_failures = 0;
if let Some(data) = status_response.data { if let Some(data) = status_response.data {
let mut record = self.repository.get_by_id(&record_id).await? let mut record = self.repository.get_by_id(&record_id).await?
.ok_or_else(|| anyhow!("找不到视频生成记录: {}", record_id))?; .ok_or_else(|| anyhow!("找不到视频生成记录: {}", record_id))?;
@ -355,6 +359,21 @@ impl VolcanoVideoService {
} }
Err(e) => { Err(e) => {
warn!("检查任务状态失败: {}", e); warn!("检查任务状态失败: {}", e);
consecutive_failures += 1;
// 如果连续失败次数达到上限,标记任务为失败
if consecutive_failures >= max_consecutive_failures {
error!("连续{}次检查任务状态失败,标记任务为失败: {}", max_consecutive_failures, e);
let mut record = self.repository.get_by_id(&record_id).await?
.ok_or_else(|| anyhow!("找不到视频生成记录: {}", record_id))?;
record.mark_as_failed(
format!("连续{}次API调用失败: {}", max_consecutive_failures, e),
Some("API_CONSECUTIVE_FAILURES".to_string())
);
self.repository.update(&record).await?;
return Err(anyhow!("连续{}次检查任务状态失败", max_consecutive_failures));
}
continue; continue;
} }
} }