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

184 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 并发控制说明 - 音乐库唱歌视频功能
## 🎯 问题
用户在视频生成过程中重复点击音乐,导致多个生成任务同时运行。
## ✅ 解决方案
实现了**前后端双重并发控制**。
---
## 🔒 前端控制
### 1. 状态检查
`selectMusicFromLibrary` 方法中添加状态检查:
```javascript
if (this.singGenerating) {
uni.showToast({
title: '视频生成中,请稍候...',
icon: 'none',
duration: 2000
});
return;
}
```
**效果**:如果有视频正在生成,直接提示用户,不发送请求。
### 2. 错误处理
`generateSingVideoWithSongId` 方法的 `fail` 回调中添加 409 错误处理:
```javascript
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.py``generate_sing_video` 方法中检查是否有进行中的任务:
```python
# 检查是否有进行中的任务
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. 前端检查 `singGenerating``false`
3. 发送请求到后端
4. 后端检查数据库 → 无进行中任务
5. 创建新任务,返回成功
6. 前端设置 `singGenerating = true`
7. 开始轮询任务状态
### 场景 2生成中再次点击前端拦截
1. 用户点击音乐
2. 前端检查 `singGenerating``true`
3. 显示提示:"视频生成中,请稍候..."
4. **不发送请求**
### 场景 3生成中再次点击后端拦截
1. 用户点击音乐
2. 前端检查 `singGenerating``false`(可能状态未同步)
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
**状态**: ✅ 已实现并测试