Download Pipeline & Recovery
How Comicarr journals snatches through post-processing and recovers in-flight work after a restart.
Comicarr keeps a durable pipeline journal so downloads and post-processing can survive restarts without double-processing completed work. Operators do not need to run a special recovery command — recovery runs automatically at startup.
Why it exists
Historically, a restart mid-download or mid-post-process could leave items stuck as “Snatched” with no further progress, or risk re-running work. The journal records each release’s stage so startup can:
- Reconstruct missing journal rows when a snatch committed but the journal write was lost
- Re-drive every open obligation through remaining stages exactly once
- Mark downloads that are truly gone from the client as failed (with a retained payload for later retry)
Stage lattice
Stages are forward-only (monotonic). A later stage never regresses to an earlier one.
| Stage | Meaning |
|---|---|
snatched | Sent to a download client / DDL queue |
downloaded | Client reports the file is available |
post_processing | Post-processor is running |
moved | File moved/copied toward the library |
post_processed | Terminal — success |
failed | Terminal — permanent failure for this attempt |
Open (still-in-flight) stages: snatched, downloaded, post_processing, moved.
Terminal stages: post_processed, failed.
Release keys
Each journal row is keyed by a release_key derived once in shared code (comicarr.app.downloads.journal). The key ties together issue identity and provider so snatch and post-process seams agree.
Notes:
- Synthetic “one-off” issue IDs (≥
900000) are not stable across restarts and are handled specially so they are not misclassified as done/gone solely via nzblog presence. - Provider labels are normalized (whitespace, case,
[RSS]suffix stripping) so RSS and active-search snatches share the same key.
Startup recovery (automatic)
On process start — after init and credential decryption, before the web server is fully serving — Comicarr runs pipeline replay once:
- Anchor reconstruction — rebuild a
snatchedjournal row only when the snatch is durable but the journal write was lost, and the release has not already advanced (avoids re-driving every historical snatch). - Snapshot open rows — read all open journal obligations.
- Classify each row against the download client / DDL state:
still— still in flight → re-queue remaining workcomplete— finished while down → advance / finish without re-snatchinggone— client no longer has the item and no “already done” signal → markfailedwith reasondownload_goneunknown— ambiguous (e.g. client unreachable) → do not mark gone; retry next start
- Throttle enqueue bursts so SQLite is not hammered against live workers.
- Cap inline full post-processing re-drives per pass so startup does not block the UI indefinitely; remaining open PP rows resume on the next start (idempotent).
You should see [RECOVERY] lines in the application log when reconstruction or re-drives occur.
Interaction with failed download handling
Journal failed / download_gone is about pipeline durability. Separate settings still control automatic re-search after failures:
| Setting | Role |
|---|---|
FAILED_DOWNLOAD_HANDLING | Enable failed-download handling |
FAILED_AUTO | Automatically search for a replacement |
BLOCKLIST_TIMER | How long a bad release stays blocklisted |
See Downloading for search/snatch behavior.
Operator tips
- Prefer a clean shutdown (
POST /api/system/shutdownordocker stopwith grace period) so workers can finish journal writes. Compose setsstop_grace_period: 30s. - If items look stuck after a crash, restart Comicarr once and check logs for
[RECOVERY]/[JOURNAL]. - Do not manually edit
pipeline_journalrows unless you know the stage lattice; invalid stages are ignored or rejected by the monotonic guard. - DDL and NZB/torrent clients are classified differently; client history eviction is treated carefully so a completed-but-pruned history row is not marked
gonewhen the library already shows post-processed.
Related
- Downloading — search loops and post-processing steps
- Direct Downloads — DDL hosts and stuck-download checks
- REST API — downloads and system endpoints