All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m6s
2.3 KiB
2.3 KiB
Subtitle Jobs Async Design
Goal
Replace the synchronous /api/generate-subtitles request with an async job flow so long-running subtitle generation can survive gateway timeouts and provide user-visible progress.
Chosen Approach
Use a single-process in-memory job store on the backend and 5-second polling on the frontend.
The backend will:
- accept subtitle generation requests
- create a job with
queuedstatus - return
202 Acceptedimmediately withjobId - continue subtitle generation in the background
- expose
GET /api/generate-subtitles/:jobIdfor status and result lookup
The frontend will:
- submit the job
- poll every 5 seconds
- map backend
stagevalues to a staged progress bar - stop polling on
succeeded,failed, or timeout
Job Model
Each subtitle job stores:
idrequestIdstatusstageprogressmessagecreatedAtupdatedAtprovidertargetLanguagefileIdfilePatherrorresult
Statuses:
queuedrunningsucceededfailed
Stages:
queuedupload_receivedpreparingcalling_providerprocessing_resultsucceededfailed
Jobs expire from memory after 1 hour.
Progress Strategy
Progress is stage-based, not byte-accurate. This avoids fake precision while still keeping the user informed.
Suggested mapping:
queued: 5upload_received: 15preparing: 30calling_provider: 70processing_result: 90succeeded: 100failed: keep last reported progress
Backend Flow
- Parse request and validate source input.
- Create a job.
- Return
202with the new job state. - Run subtitle generation in a detached async task.
- Update the job on each pipeline stage.
- Store final result or error.
- Clean up uploaded temp files after background completion.
Frontend Flow
- Doubao still uploads to Ark Files first and waits for file readiness.
- Frontend posts to
/api/generate-subtitles. - Frontend polls
/api/generate-subtitles/:jobIdevery 5 seconds. - Progress UI updates from backend job status and stage.
- Final result is normalized into
SubtitlePipelineResult.
Risks
- In-memory jobs are lost on restart.
- Single-instance memory state will not scale across multiple backend replicas.
- Upload time can still be slow, but the long model invocation is no longer tied to one HTTP response.