fix(cover): 封面 API MediaKit 抽帧短超时,避免请求挂死 #1460

Merged
xiaoxia merged 1 commits from fix/cover-mediakit-timeout into develop 2026-08-23 00:15:06 +08:00
Owner

问题

PR #1459 新增的 E1/E2 兜底抽帧在 API 请求内同步调用 mk_client.extract_frames(),使用默认 max_poll_attempts=30 * poll_interval=2s,MediaKit 不可达或任务长时间 processing 时单次调用最多阻塞约 60s。E1 失败后 E2 还会再调用,请求可达 2 分钟,前端一直转圈。

修改

  • E1(渲染视频抽帧)和 E2(源素材抽帧)显式设置:poll_interval=2.0、max_poll_attempts=5、max_retries=0,API 请求内兜底最多等约 10s,超时快速失败返回 400,不再阻塞。
  • Worker 端 generation.py 抽帧保持默认 30 次轮询(后台任务,可以等待),核心路径仍是预览渲染完成后写入 gen_task.cover_url,由 A/B/C 步骤命中。
  • 更新过期注释(前端已改回原生后端渲染,不再是纯 Canvas/WebCodecs)。

验证

  • pytest tests/unit/test_generation_cover.py -q → 24 passed
  • py_compile OK

部署后验证流程

  1. staging 重新生成预览(Worker 会在上传 OSS 后抽帧写 cover_url)
  2. 点击自动生成封面,应从步骤 A/B/C 快速命中 cover_url
  3. 极端情况下 MediaKit 抽帧失败,API 也会在 ~10s 内返回,不再挂死
## 问题 PR #1459 新增的 E1/E2 兜底抽帧在 API 请求内同步调用 mk_client.extract_frames(),使用默认 max_poll_attempts=30 * poll_interval=2s,MediaKit 不可达或任务长时间 processing 时单次调用最多阻塞约 60s。E1 失败后 E2 还会再调用,请求可达 2 分钟,前端一直转圈。 ## 修改 - E1(渲染视频抽帧)和 E2(源素材抽帧)显式设置:poll_interval=2.0、max_poll_attempts=5、max_retries=0,API 请求内兜底最多等约 10s,超时快速失败返回 400,不再阻塞。 - Worker 端 generation.py 抽帧保持默认 30 次轮询(后台任务,可以等待),核心路径仍是预览渲染完成后写入 gen_task.cover_url,由 A/B/C 步骤命中。 - 更新过期注释(前端已改回原生后端渲染,不再是纯 Canvas/WebCodecs)。 ## 验证 - pytest tests/unit/test_generation_cover.py -q → 24 passed - py_compile OK ## 部署后验证流程 1. staging 重新生成预览(Worker 会在上传 OSS 后抽帧写 cover_url) 2. 点击自动生成封面,应从步骤 A/B/C 快速命中 cover_url 3. 极端情况下 MediaKit 抽帧失败,API 也会在 ~10s 内返回,不再挂死
xiaoxia added 1 commit 2026-08-23 00:04:38 +08:00
fix(cover): short MediaKit polling timeout in API cover endpoint (E1/E2)
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 50s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 39s
AI Code Review / AI Code Review (pull_request) Successful in 1m36s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m38s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m45s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m53s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m14s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m35s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m22s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m49s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 5m51s
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
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 / 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
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m3s
CI/CD Pipeline / CI Gate (pull_request) Successful in 7s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 57s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 1m32s
005f500ee1
E1/E2 fallback calls used default 30 polling attempts * 2s = 60s each,
causing the cover API to hang ~2 minutes when MediaKit is slow/unreachable.
Set max_poll_attempts=5, poll_interval=2, max_retries=0 for API-side
fallback so it fails fast (~10s) instead of blocking the request.

Worker-side extraction keeps default timeout (background task, safe).
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:否
  • 阻塞级问题数量:0 个

📊 审查概览

  • 整体评价:通过
  • 建议级问题数量:1 个

🔴 阻塞级问题(必须修复)

💡 改进建议(不阻塞合并)

  1. [apps/api/app/api/routes/generation_cover.py: 257] 建议调整标准库导入位置
    • 具体内容:代码在函数内部 generate_cover 中使用了 import re as _re。虽然 Python 允许在函数内导入以优化启动时间或避免循环依赖,但在 Web 服务(如 FastAPI)的热加载或长期运行进程中,将标准库导入放在文件顶部通常更符合 Python 编码规范(PEP 8),也有助于提高代码可读性。建议移至文件头部。

良好实践

  1. 超时控制优化:在调用 video_svc.extract_frames 时显式增加了 poll_intervalmax_poll_attemptsmax_retries 参数,有效防止了因抽帧任务卡死导致 API 请求长时间阻塞,符合“短超时、不阻塞”的业务兜底逻辑。
  2. URL 清理逻辑:使用正则 r"(?<!:)//" 清理 URL 中的多余斜杠,且使用了负向后瞻 (?<!:) 精准保护了 http:// 等协议头不被破坏,逻辑严谨。
  3. 注释更新:及时更新了注释,准确描述了代码变更后的业务含义(如步骤 E 的兜底逻辑),有助于后续维护。

🤖 由 AI 代码审查机器人自动生成 | 2026-08-22 16:06:14 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:否 - 阻塞级问题数量:0 个 ### 📊 审查概览 - 整体评价:通过 - 建议级问题数量:1 个 ### 🔴 阻塞级问题(必须修复) 无 ### 💡 改进建议(不阻塞合并) 1. **[apps/api/app/api/routes/generation_cover.py: 257] 建议调整标准库导入位置** - 具体内容:代码在函数内部 `generate_cover` 中使用了 `import re as _re`。虽然 Python 允许在函数内导入以优化启动时间或避免循环依赖,但在 Web 服务(如 FastAPI)的热加载或长期运行进程中,将标准库导入放在文件顶部通常更符合 Python 编码规范(PEP 8),也有助于提高代码可读性。建议移至文件头部。 ### ✅ 良好实践 1. **超时控制优化**:在调用 `video_svc.extract_frames` 时显式增加了 `poll_interval`、`max_poll_attempts` 和 `max_retries` 参数,有效防止了因抽帧任务卡死导致 API 请求长时间阻塞,符合“短超时、不阻塞”的业务兜底逻辑。 2. **URL 清理逻辑**:使用正则 `r"(?<!:)//"` 清理 URL 中的多余斜杠,且使用了负向后瞻 `(?<!:)` 精准保护了 `http://` 等协议头不被破坏,逻辑严谨。 3. **注释更新**:及时更新了注释,准确描述了代码变更后的业务含义(如步骤 E 的兜底逻辑),有助于后续维护。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-22 16:06:14 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->

🚀 预览环境已部署

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

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

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

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

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

🗑️ 预览环境已清理

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

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

🗑️ **预览环境已清理** PR #1460 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.