fix(worker+api): batch title vfb alignment, race-free config, auto-queue (3 bugs) #2097
Merged
xiaoxia
merged 4 commits from 2026-09-29 19:51:40 +08:00
fix/gpu-direct-title-vfb-alignment into develop
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
efb7fa5729 |
style: auto-format with black + isort + ruff + prettier [skip ci-format-check]
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
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 / 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 / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped 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 / PR Build API Image (pull_request) Successful in 47s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m28s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m47s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m54s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 7m6s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 8m43s
AI Code Review / AI Code Review (pull_request) Successful in 10m46s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m49s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 15m58s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 24m52s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 4m25s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 5m1s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 1h3m21s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s
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
|
||
|
|
5e1520230f |
test(api+worker): align unit tests with #2098 soft user limit + override refactor
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
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 / 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 / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped 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 / PR Build API Image (pull_request) Successful in 48s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m29s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m52s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m59s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 6m39s
AI Code Review / AI Code Review (pull_request) Successful in 6m52s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 8m53s
CI/CD Pipeline / Validate - Style (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
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
- Bug B: check_queue_limits no longer raises UserPendingLimitExceeded (user limit is soft); only global GLOBAL_PENDING_LIMIT hard-rejects with 503. - safe_enqueue_generation_task user over-limit is warning-only (pre/post enqueue); GlobalQueueFull still hard-rejects/rolls-back. - Preview route (/generation/preview) user-pending pre-check removed to match batch/generation/retry routes; only global 503 pre-check kept. - Route enqueue-loop: UserPendingLimitExceeded except branch removed; all-failed rate-limit response only triggers on GlobalQueueFull (503). - Tests rewritten to reflect new semantics (197 queue/preview/batch/pipeline tests pass). - test_worker_generate_video_task_binding: replaced legacy _sync_task_config_to_plan helper test with _build_task_config_override + _download_voice_for_task (Bug A refactor). - USER_PENDING_LIMIT constant verified at 20 (soft cap). |
||
|
|
96bcec5fdd |
fix(worker+api): resolve batch title race + auto-queue pending tasks (#2098)
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
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 / 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 / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped 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 / PR Build API Image (pull_request) Successful in 1m3s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m23s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m3s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 4m8s
AI Code Review / AI Code Review (pull_request) Successful in 7m3s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 8m12s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 8m39s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 9m47s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m51s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 14m41s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 24m23s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web 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 / CI Gate (pull_request) Failing after 2s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
Two batch-rendering bugs found from staging logs (6-video batch 17:30-17:43):
Bug A (P1) — title_config race when same plan renders concurrently:
_sync_task_config_to_plan wrote each task's title_config/bgm/resolution
to the shared plan.config row, then RenderAdapter.render_plan read back
from plan.config during rendering. If two tasks sharing the same plan
(e.g. batch retry, preview+render, retry+new) ran concurrently, Task B's
write could overwrite Task A's title before Task A's ffmpeg read it,
producing videos with the wrong title text/style.
Fix: stop mutating plan.config in the worker render path. Introduce
task_config_override threading through render_plan / _do_render /
UnifiedRenderService; URS reads config via _effective_config() which
does a deep-copy plan.config merged with per-task override (title/bgm/
export). _build_task_config_override builds the override dict (with
field-name normalization: font_size→size, font_color→color) from
task_info, and _download_voice_for_task handles voiceover download
independently. plan.config is left as-authored by the API writeback;
concurrent tasks no longer race on it.
Files:
- apps/worker/video_processing/unified_render_service.py: add
override_config param + _cfg_section/_effective_config helpers;
replace all render-time self.plan.config reads (title/subtitle/bgm/
export/TTS) with _effective_config().
- apps/worker/video_processing/render_adapter.py: render_plan/_do_render/
_prepare_bgm accept task_config_override, merge into bgm/export reads,
forward to URS.
- apps/worker/worker_app/tasks/generation.py: replace
_sync_task_config_to_plan (which wrote plan.config) with
_build_task_config_override + _download_voice_for_task; pass
task_config_override to render_plan.
Bug B (P0) — USER_PENDING_LIMIT=3 returns HTTP 429, blocks batch submit:
Pre-check in create_generation_task rejected the whole batch with 429
USER_QUEUE_FULL once user had ≥3 pending tasks; UI showed 'wait ~4 min'
and prevented any more submissions. Users expect to submit a batch of
6 and have them queue naturally (worker concurrency=2).
Fix:
- USER_PENDING_LIMIT 3→20 (soft cap for abuse protection, supports
typical batch sizes of 6-10 with headroom).
- Remove user-level 429 rejection from pre-check, retry endpoint,
single-task confirm endpoint, and safe_enqueue (user path now logs
a warning and continues to enqueue). Global GLOBAL_PENDING_LIMIT=20
is retained as a hard 503 system-busy guard.
- safe_enqueue post-enqueue check: user-over only logs, does not
fail the task or raise.
- Batch loop UserPendingLimitExceeded except branch now treats it as
a successful enqueue (should not trigger in practice).
Files:
- apps/api/app/core/task_enqueue.py: limit 3→20; user checks log-only.
- apps/api/app/api/routes/generation_tasks.py: remove user pre-check
429; soften retry/single/batch except branches.
Stacked on PR #2095/#2097 which already fixed title baseline/width-scaling
and default-constant alignment with CPU video_filter_builder.
Tests:
- tests/unit/test_gpu_direct_pipeline.py: 30 passed
- tests/unit/test_render_adapter_pure.py: 18 passed
- ruff check/format clean; py_compile clean
|
||
|
|
dfc5e5a5b6 |
fix(worker): align gpu-direct title defaults (size/margin/bold) with CPU vfb path
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m12s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m6s
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 / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped 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 / PR Build Worker Image (pull_request) Successful in 2m26s
AI Code Review / AI Code Review (pull_request) Successful in 6m55s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 9m28s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 9m32s
CI/CD Pipeline / PR Build API Image (pull_request) Failing after 8m40s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 11m15s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 11m45s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m46s
CI/CD Pipeline / Validate - Security (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
PR #2095 fixed title baseline positioning and width-scaling but didn't fully align default constants with the CPU video_filter_builder path, causing GPU rendered titles to appear slightly smaller / higher / bolder-differently than the CPU/ASS preview the template was authored against. This shows up in both single and batch GPU renders since every variant shares the same gpu_direct pipeline. Root causes in PR #2095 defaults: - Default title size 36@720p vs config_schemas DEFAULT 48 / vfb default 48 - Top/bottom margin 40@720p (PAD16+margin24) vs vfb _scale_title_len(50) - Subtitle bottom margin 60@720p vs vfb 50 - Faux bold used same-color 1px border (white-on-white invisible for default white text; red-on-red for colored) vs vfb black 2px (intentional choice per #2001 to avoid double-print/halo artifact) - margin_top was treated as absolute y offset, now correctly added on top of base margin (matches vfb additive semantics) - subtitle stroke/bold block referenced uninitialized s_borderw (ruff F821) — added proper init + stroke parsing consistent with title block Changes: - TITLE_DEFAULT_MARGIN_TOP/BOTTOM = 50 (was 24+PAD=40) - SUBTITLE_DEFAULT_MARGIN_BOTTOM = 50 (was 60) - TITLE_FAUX_BOLD_WIDTH = 2, border color = #000000 (was 1, same as text) - default title size 48@720p (was 36) - margin_top from cfg added on top of base 50 (additive, same as vfb) - subtitle: init s_borderw/s_border_color, parse stroke dict before bold check - bottom position: y = h - th - margin_bottom (correct baseline; previously used margin_top variable which was misleading but numerically equivalent before margin split; now uses explicit margin_bottom) Tests updated to new expected scaled values (1280x720 scale=1.778: fontsize 85, y=89, bold borderw=4 black; 1080x1920 vertical: fontsize 72, y=75; margin_top=100 user offset => y=267). Added test_title_bold_false_disables_faux_bold. Batch investigation notes (separate findings, not bugs in this PR): - per-variant plan config is correctly deep-copied via clone_plan_for_variant (config=dict(source.config or {})); title text per-variant via titles[] override; voice per-variant independent download with #1749 strict guards; bgm merged via merge_bgm_config — batch passthrough chain is correct. - Worker generation concurrency = 2 (compose.yml default); USER_PENDING_LIMIT=3, 6 tasks will enqueue in two waves (first 3 → then next 3 as workers free up); GLOBAL_PENDING_LIMIT allows it. This is expected behavior, not a bug. - Legacy key mismatch: subtitle_render_engine.py reads plan_config['subtitle_config'] (snake_case) but normalize_plan_config writes 'subtitle' short key. This file is not imported by unified_render_service (which uses render_subtitles.py with explicit subtitle_config= parameter), so no runtime impact; left for separate cleanup. - Frontend usePlanConfigLoader.ts reads config.title_config snake_case while backend writes 'title' short key — frontend-only issue for subsequent edit sessions, out of backend scope. |