fix: 修复 AI Code Review 阻塞级问题(useCanvasPlayer 解码策略+资源泄漏+useStep6Cover 轮询超时) #1447

Closed
xiaoxia wants to merge 2 commits from fix/ai-code-review-blocking into develop
Owner

修复内容

修复 AI Code Review 在 PR #1437、#1438、#1439 中标记的 5 个阻塞级问题。

useCanvasPlayer.ts(PR #1437 + #1438)

1. 初始化解码策略(#1437 阻塞1)

  • 初始化改为按需解码:只解码前 3 个片段
  • 新增 decodeAroundPosition() 函数,在渲染循环中每 200ms 动态解码当前 ±1 片段
  • seek 时重置 decodedSegmentsRef 并立即重新解码
  • 解决:frameQueue 环形缓冲区大小固定为 10,全量解码导致旧帧被丢弃引发黑屏

2. 异步同步机制(#1437 阻塞2)

  • 确认 demuxSegment 已正确使用 Promise + onSamples 回调 resolve
  • setTimeout 仅保留为 5 秒超时保护,无需额外改动

3. VideoFrame 资源泄漏(#1438)

  • 新增 lastDrawnFrameRef 追踪上一帧
  • renderFrame 中绘制新帧前关闭上一帧(frame?.close()
  • destroy/seek 时也做清理
  • 解决:渲染循环删除了 frame.close() 导致内存泄漏和浏览器崩溃

useStep6Cover.ts(PR #1439)

4. 轮询超时机制(#1439 阻塞1)

  • 增加 pollCount 计数器,最大 60 次
  • 增加 setTimeout 120_000 总超时保护
  • 双重超时:任一触发即 reject 并提示"预览生成超时,请稍后重试"
  • 解决:setInterval 无限轮询,后端异常时前端永久卡住

5. 400 错误处理(#1439 阻塞2)

  • 检查 err.response.data.codeerr.response.data.message
  • 仅当匹配"预览缺失"模式(PREVIEW code 或中英文正则匹配)时才自动修复
  • 其他 400 走常规错误处理
  • 解决:所有 400 错误都触发预览创建自动修复,误判其他类型错误

验证

  • TypeScript 编译 零错误
  • ESLint 零错误

Closes #1437, #1438, #1439

## 修复内容 修复 AI Code Review 在 PR #1437、#1438、#1439 中标记的 5 个阻塞级问题。 ### useCanvasPlayer.ts(PR #1437 + #1438) **1. 初始化解码策略(#1437 阻塞1)** - 初始化改为按需解码:只解码前 3 个片段 - 新增 `decodeAroundPosition()` 函数,在渲染循环中每 200ms 动态解码当前 ±1 片段 - seek 时重置 `decodedSegmentsRef` 并立即重新解码 - 解决:frameQueue 环形缓冲区大小固定为 10,全量解码导致旧帧被丢弃引发黑屏 **2. 异步同步机制(#1437 阻塞2)** - 确认 demuxSegment 已正确使用 Promise + onSamples 回调 resolve - setTimeout 仅保留为 5 秒超时保护,无需额外改动 **3. VideoFrame 资源泄漏(#1438)** - 新增 `lastDrawnFrameRef` 追踪上一帧 - renderFrame 中绘制新帧前关闭上一帧(`frame?.close()`) - destroy/seek 时也做清理 - 解决:渲染循环删除了 frame.close() 导致内存泄漏和浏览器崩溃 ### useStep6Cover.ts(PR #1439) **4. 轮询超时机制(#1439 阻塞1)** - 增加 `pollCount` 计数器,最大 60 次 - 增加 `setTimeout 120_000` 总超时保护 - 双重超时:任一触发即 reject 并提示"预览生成超时,请稍后重试" - 解决:setInterval 无限轮询,后端异常时前端永久卡住 **5. 400 错误处理(#1439 阻塞2)** - 检查 `err.response.data.code` 和 `err.response.data.message` - 仅当匹配"预览缺失"模式(PREVIEW code 或中英文正则匹配)时才自动修复 - 其他 400 走常规错误处理 - 解决:所有 400 错误都触发预览创建自动修复,误判其他类型错误 ### 验证 - TypeScript 编译 ✅ 零错误 - ESLint ✅ 零错误 Closes #1437, #1438, #1439
xiaoxia added 1 commit 2026-08-19 20:16:57 +08:00
fix: 修复 AI Code Review 阻塞级问题(useCanvasPlayer 解码策略+资源泄漏+useStep6Cover 轮询超时)
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 22s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m9s
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m1s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 2m1s
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 1m46s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m16s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m58s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 3m1s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m25s
AI Code Review / AI Code Review (pull_request) Successful in 4m44s
CI/CD Pipeline / Validate - Code Quality (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
58a7cc20c9
- useCanvasPlayer: 初始化改为按需解码(前3片段+decodeAroundPosition动态加载)
- useCanvasPlayer: 新增 lastDrawnFrameRef 追踪,绘制新帧前关闭上一帧防止内存泄漏
- useCanvasPlayer: seek 时重置解码状态并重新解码当前区域
- useStep6Cover: 轮询增加 pollCount(max 60) + setTimeout 120s 双重超时保护
- useStep6Cover: 400错误精确匹配预览缺失模式,避免误触发自动修复

Closes: #1437, #1438, #1439

🚀 预览环境已部署

项目 详情
PR号 #1447
预览链接 https://pr-1447.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1447 | | 预览链接 | [https://pr-1447.preview.xiaoxiajianji.com](https://pr-1447.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
Collaborator

代码审查结果 - PR #1447

⚠️ 问题(2个需要修改)

  1. apps/web/src/pages/generate/hooks/useCanvasPlayer.ts 第641行:解码状态标记逻辑错误,导致解码失败时无法重试。

    • 问题描述:代码在 await decodeSegment(buffer, meta) 之前就执行了 decodedSegmentsRef.current.add(i)。如果 decodeSegment 抛出异常(如网络错误或解码错误),该索引已被标记为“已解码”,后续重试时会被跳过,导致视频播放卡顿或黑屏且无法恢复。
    • 修改建议:将 decodedSegmentsRef.current.add(i) 移至 await decodeSegment(buffer, meta) 之后,确保只有解码成功才标记。
  2. apps/web/src/pages/generate/hooks/useCanvasPlayer.ts 第823行:初始化解码循环存在同样的状态标记错误。

    • 问题描述:同上,初始化时也在 await decodeSegment 之前标记了状态,存在同样的无法重试风险。
    • 修改建议:将 decodedSegmentsRef.current.add(i) 移至 await decodeSegment(buffer, meta) 之后。
  3. apps/web/src/pages/generate/hooks/useStep6Cover.ts 第160-163行:轮询超时定时器未清理,导致潜在的 Promise rejection 泄露。

    • 问题描述:代码中设置了 setTimeout 作为总超时保护(2分钟),但如果轮询在2分钟内成功(Promise resolve),这个 setTimeout 并没有被清除。当2分钟到达时,它会尝试 reject 一个已经 settled 的 Promise,在控制台抛出 "UnhandledPromiseRejectionWarning" 或类似错误。
    • 修改建议:将 setTimeout 的 ID 赋值给一个变量(如 timeoutId),在 resolve()clearInterval(poll) 的同时执行 clearTimeout(timeoutId)

💡 建议(2个可选)

  1. apps/web/src/pages/generate/hooks/useCanvasPlayer.ts 第632行:查找当前片段索引的循环效率较低。

    • 建议描述:循环内部每次都判断 currentTime >= metas[metas.length - 1].globalEndTime 是冗余的。建议将边界检查(时间超过最后一个片段)移到循环外部,或者使用二分查找提升性能(如果片段数量极多)。
  2. apps/web/src/pages/generate/hooks/useStep6Cover.ts 第141行:轮询超时逻辑存在冗余。

    • 建议描述:代码中同时存在 pollCount > maxPolls(60次 * 3秒 = 180秒)和 setTimeout(120秒)两套超时机制。由于 setTimeout 时间更短,pollCount 的判断逻辑永远不会触发。建议移除 pollCount 相关判断,仅保留 setTimeout,或者调整数值使其逻辑一致。

格式检查通过 | 逻辑审查需修改 | ⚠️ 建议关注性能


🤖 由 AI 代码审查机器人自动生成 | 2026-08-19 12:21:41 | 模型:

## 代码审查结果 - PR #1447 ### ⚠️ 问题(2个需要修改) 1. **apps/web/src/pages/generate/hooks/useCanvasPlayer.ts 第641行**:解码状态标记逻辑错误,导致解码失败时无法重试。 - **问题描述**:代码在 `await decodeSegment(buffer, meta)` 之前就执行了 `decodedSegmentsRef.current.add(i)`。如果 `decodeSegment` 抛出异常(如网络错误或解码错误),该索引已被标记为“已解码”,后续重试时会被跳过,导致视频播放卡顿或黑屏且无法恢复。 - **修改建议**:将 `decodedSegmentsRef.current.add(i)` 移至 `await decodeSegment(buffer, meta)` 之后,确保只有解码成功才标记。 2. **apps/web/src/pages/generate/hooks/useCanvasPlayer.ts 第823行**:初始化解码循环存在同样的状态标记错误。 - **问题描述**:同上,初始化时也在 `await decodeSegment` 之前标记了状态,存在同样的无法重试风险。 - **修改建议**:将 `decodedSegmentsRef.current.add(i)` 移至 `await decodeSegment(buffer, meta)` 之后。 3. **apps/web/src/pages/generate/hooks/useStep6Cover.ts 第160-163行**:轮询超时定时器未清理,导致潜在的 Promise rejection 泄露。 - **问题描述**:代码中设置了 `setTimeout` 作为总超时保护(2分钟),但如果轮询在2分钟内成功(Promise resolve),这个 `setTimeout` 并没有被清除。当2分钟到达时,它会尝试 reject 一个已经 settled 的 Promise,在控制台抛出 "UnhandledPromiseRejectionWarning" 或类似错误。 - **修改建议**:将 `setTimeout` 的 ID 赋值给一个变量(如 `timeoutId`),在 `resolve()` 或 `clearInterval(poll)` 的同时执行 `clearTimeout(timeoutId)`。 ### 💡 建议(2个可选) 1. **apps/web/src/pages/generate/hooks/useCanvasPlayer.ts 第632行**:查找当前片段索引的循环效率较低。 - **建议描述**:循环内部每次都判断 `currentTime >= metas[metas.length - 1].globalEndTime` 是冗余的。建议将边界检查(时间超过最后一个片段)移到循环外部,或者使用二分查找提升性能(如果片段数量极多)。 2. **apps/web/src/pages/generate/hooks/useStep6Cover.ts 第141行**:轮询超时逻辑存在冗余。 - **建议描述**:代码中同时存在 `pollCount > maxPolls`(60次 * 3秒 = 180秒)和 `setTimeout`(120秒)两套超时机制。由于 `setTimeout` 时间更短,`pollCount` 的判断逻辑永远不会触发。建议移除 `pollCount` 相关判断,仅保留 `setTimeout`,或者调整数值使其逻辑一致。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-19 12:21:41 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia added 1 commit 2026-08-19 20:25:33 +08:00
style: 修复 prettier 格式问题(useStep6Cover 长行换行)
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 25s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m42s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 2m10s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m6s
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m18s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m36s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m15s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m52s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m51s
AI Code Review / AI Code Review (pull_request) Successful in 6m59s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 8m18s
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 27s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 25s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 34s
03b6e0e89a
auto-approve-bot approved these changes 2026-08-19 20:28:23 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-08-19 20:28:24 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
xiaoxia closed this pull request 2026-08-19 20:48:12 +08:00

🗑️ 预览环境已清理

PR #1447 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1447 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 25s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m42s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 2m10s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m6s
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m18s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m36s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m15s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m52s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m51s
AI Code Review / AI Code Review (pull_request) Successful in 6m59s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 8m18s
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 27s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 25s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 34s

Pull request closed

Sign in to join this conversation.