P1 transcoder: ack message only after successful metadata update #50
Copy link
Copy link
Closed
Labels
area:transcoderarea:transcoderarea:transcoderphase:17Phase 17 hardening and refactors: shared Go module, pipeline fixesPhase 17 hardening and refactors: shared Go module, pipeline fixes
Description
Если update_status("ready") упал, transcoder всё равно делает basic_ack (consumer.py:832,926) — видео навсегда «processing», ретрая не будет.
Фикс: ack только после успешного update_status; иначе basic_nack(requeue=False) → DLX/retry-очередь. Покрыть on_message retry/DLQ тестами.
Verify: тест «metadata упал → ретрай, не ack».
Источник: docs/REVIEW-2026-09-13-merged.md M7
Автоматически создано из сводного ревью. Сверяй актуальность номеров строк — они зафиксированы на коммите 91efb5b.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:transcoderarea:transcoderarea:transcoderphase:17Phase 17 hardening and refactors: shared Go module, pipeline fixesPhase 17 hardening and refactors: shared Go module, pipeline fixes
Activity
SlavaKuntsov commentedon Sep 18, 2026
Agent review — iteration 1
Findings
services/transcoder/app/consumer.py:832-837— metadata-only failure triggers a full re-transcode/re-upload on retry (renditions already in MinIO). Correct but wasteful; bounded byMAX_RETRIES=3. Mitigated with a code comment; follow-up ticket candidate for a ready-PATCH-only retry path.services/transcoder/app/consumer.py:915-924— retry-publish-failure branch was untested (part of the requested retry/DLQ surface). Fixed: addedtest_handle_message_publish_failure_marks_failed_and_dlqs.services/transcoder/app/consumer.py:669-671— poison messages (invalid JSON) are acked and dropped, never dead-lettered. Pre-existing, out of scope.x-retry-count.docs/services-pipeline.md/services/transcoder/README.mddon't document ack semantics at this level — nothing factually wrong after this change.Verdict
ready for PR
Verification
uv run --project services/transcoder pytest services/transcoder/tests -q— 25 passeduv run --project services/auth pytest services/auth/tests -q— 18 passedblack --check/flake8/mypy(transcoder) — cleanSlavaKuntsov commentedon Sep 18, 2026
Ready for review
Implemented
process_messageraises when the finalupdate_status(video_id, "ready", ...)fails, so the consumer no longer acks a video that would stay «processing» forever; raw-object cleanup still happens only after metadata confirms ready.on_messageclosure extracted to module-levelhandle_message(behavior-identical): ack only afterprocess_messagesucceeds; on failure republish tovideo.uploaded.retrywith incrementedx-retry-count(TTL dead-letters back to the main queue), and afterMAX_RETRIESmarkfailed+basic_nack(requeue=False)→ DLX → DLQ.handle_messageack-after-success; metadata failure → retry republish + ack, not silent ack; incoming retry count respected; retries exhausted →failed+ nack to DLQ; retry publish failure →failed+ nack to DLQ.Acceptance criteria
update_status("ready")basic_nack(requeue=False)→ DLX/DLQVerification
uv run --project services/transcoder pytest services/transcoder/tests -q— 25 passeduv run --project services/auth pytest services/auth/tests -q— 18 passedblack --check,flake8,mypy(transcoder) — cleanmake e2e— not run (requires full docker compose stack)Review cycle
Suggested PR title
fix(transcoder): ack only after successful metadata ready updateSlavaKuntsov commentedon Sep 18, 2026
Pull request opened
#78 — will auto-close via
Closes #50on merge.Project status:
In review(synced after PR creation).Verification
uv run --project services/transcoder pytest services/transcoder/tests -q— 25 passeduv run --project services/auth pytest services/auth/tests -q— 18 passedblack --check,flake8,mypy(transcoder) — cleanRemaining risks
MAX_RETRIES=3, re-uploads idempotent) — follow-up candidate.make e2enot run (requires full docker compose stack).