Ai_GirlFriend/并发控制说明.md
2026-02-04 18:47:56 +08:00

4.6 KiB
Raw Blame History

并发控制说明 - 音乐库唱歌视频功能

🎯 问题

用户在视频生成过程中重复点击音乐,导致多个生成任务同时运行。

解决方案

实现了前后端双重并发控制


🔒 前端控制

1. 状态检查

selectMusicFromLibrary 方法中添加状态检查:

if (this.singGenerating) {
    uni.showToast({ 
        title: '视频生成中,请稍候...', 
        icon: 'none', 
        duration: 2000 
    });
    return;
}

效果:如果有视频正在生成,直接提示用户,不发送请求。

2. 错误处理

generateSingVideoWithSongId 方法的 fail 回调中添加 409 错误处理:

fail: (err) => {
    uni.hideLoading();
    console.error('生成失败:', err);
    
    // 检查是否是 409 错误(已有任务进行中)
    if (err.statusCode === 409 || (err.data && err.data.detail && err.data.detail.includes('进行中'))) {
        uni.showModal({
            title: '提示',
            content: '已有视频正在生成中,请稍后再试',
            showCancel: false
        });
    } else {
        uni.showModal({
            title: '生成失败',
            content: '网络错误,请重试',
            showCancel: false
        });
    }
}

效果:如果后端返回 409 错误,显示友好的提示信息。


🔒 后端控制

1. 任务检查

后端在 lover/routers/sing.pygenerate_sing_video 方法中检查是否有进行中的任务:

# 检查是否有进行中的任务
existing_task = db.query(SingSongVideo).filter(
    SingSongVideo.user_id == user.id,
    SingSongVideo.status.in_(['pending', 'processing'])
).first()

if existing_task:
    raise HTTPException(status_code=409, detail="已有视频生成任务进行中,请稍后再试")

效果:如果有进行中的任务,返回 409 错误。


📊 控制流程

场景 1正常生成

  1. 用户点击音乐
  2. 前端检查 singGeneratingfalse
  3. 发送请求到后端
  4. 后端检查数据库 → 无进行中任务
  5. 创建新任务,返回成功
  6. 前端设置 singGenerating = true
  7. 开始轮询任务状态

场景 2生成中再次点击前端拦截

  1. 用户点击音乐
  2. 前端检查 singGeneratingtrue
  3. 显示提示:"视频生成中,请稍候..."
  4. 不发送请求

场景 3生成中再次点击后端拦截

  1. 用户点击音乐
  2. 前端检查 singGeneratingfalse(可能状态未同步)
  3. 发送请求到后端
  4. 后端检查数据库 → 有进行中任务
  5. 返回 409 错误:"已有视频生成任务进行中,请稍后再试"
  6. 前端捕获 409 错误
  7. 显示提示:"已有视频正在生成中,请稍后再试"

🎯 用户体验

提示信息

  1. 前端拦截

    • 提示:视频生成中,请稍候...
    • 类型Toast2秒后自动消失
    • 场景:用户在生成中点击
  2. 后端拦截

    • 提示:已有视频正在生成中,请稍后再试
    • 类型Modal需要点击确定
    • 场景:前端状态未同步时

状态管理

  • singGenerating:标记是否有视频正在生成
  • singGeneratingTaskId:当前生成任务的 ID
  • 生成完成后自动重置状态

🔍 测试方法

测试 1前端拦截

  1. 点击音乐 A开始生成
  2. 立即再次点击音乐 A
  3. 应该看到 Toast"视频生成中,请稍候..."
  4. 不应该发送新的请求

测试 2后端拦截

  1. 点击音乐 A开始生成
  2. 刷新页面(清除前端状态)
  3. 再次点击音乐 A
  4. 应该看到 Modal"已有视频正在生成中,请稍后再试"
  5. 后端日志应该显示 409 错误

测试 3生成完成后

  1. 点击音乐 A等待生成完成
  2. 再次点击音乐 A
  3. 应该立即成功(使用缓存)
  4. 不应该看到任何拦截提示

💡 技术亮点

  1. 双重保护:前端 + 后端,确保不会有重复任务
  2. 友好提示:区分前端拦截和后端拦截,提供不同的提示
  3. 状态同步:使用 singGenerating 标记,自动管理状态
  4. 错误处理:完善的 409 错误处理逻辑

📝 注意事项

  1. 前端状态可能因为刷新页面而丢失,所以需要后端检查
  2. 后端检查是最终保障,确保数据库不会有重复任务
  3. 409 错误是标准的 HTTP 状态码,表示"冲突"
  4. 生成完成后会自动重置 singGenerating 状态

并发控制说明版本: 1.0
创建时间: 2026-02-04 18:30
状态: 已实现并测试