Worker¶
The worker processes the job queue sequentially (FIFO).
Automatic startup (UI)¶
server.py (lifespan + _ensure_worker()) → start_background_worker():
- Only one worker at a time (
worker.pidcheck) - Daemon process separate from uvicorn/FastAPI
warmup_asr()in the worker before the loop (NeMo import on the worker main thread)
Manual startup¶
Useful for:
- Docker (one container = UI + worker subprocess, or
workeronly) - Headless debugging
- Splitting UI and processing across machines (same
queue.dbon NFS — not yet documented/tested)
Loop¶
while True:
job = claim_next_job() # atomic SQLite
if job is None:
sleep(poll_interval)
continue
run_pipeline(job.id)
Crash recovery and disk sync¶
On worker startup:
recover_orphaned_running_jobs()— resets jobs left inrunningback toqueuedreconcile_jobs_with_disk()— alignsqueue.dbwith folders on disk
The UI runs the same reconcile in its lifespan and when opening / and /jobs.
PID file¶
data/output/jobs/worker.pid — PID of the active worker process.
scripts/restart_ui.py also stops workers and removes the PID file.
Docker¶
In the Docker image, sbobina docker-ui starts the UI plus a worker subprocess. ASR models live in /models/ in the image.
For worker-only deploy (no UI):
Do not¶
- Do not start multiple workers on the same
queue.db(claim races — mitigated by SQLite but discouraged) - Do not use in-process threads for NeMo inside the web server