Skip to content

feat: atomic direct-download fallback + ranked-hierarchy continuation - #246

Open
jtstothard wants to merge 2 commits into
kikootwo:mainfrom
jtstothard:feat/atomic-fallback-and-ranked-continuation
Open

feat: atomic direct-download fallback + ranked-hierarchy continuation#246
jtstothard wants to merge 2 commits into
kikootwo:mainfrom
jtstothard:feat/atomic-fallback-and-ranked-continuation

Conversation

@jtstothard

@jtstothard jtstothard commented Jul 15, 2026

Copy link
Copy Markdown

Summary

  • make direct-download fallback atomic so only one path claims the transition and enqueues fallback search
  • continue to the next ranked candidate for both ebooks and audiobooks after permanent download failures
  • preserve existing downloader routing and transient vs permanent retry semantics

What Changed

  • replace the provider-specific fallback helper with a generic direct-download-fallback
  • apply ranked continuation in the download/monitor paths without double-counting searchAttempts
  • use isFallback to skip direct-download sources during fallback re-search

Verification

  • npm exec prisma generate
  • npx tsc --noEmit
  • npm run test2596 passed, 4 skipped, 0 failed
  • npm run build

Issue refs

…ation

When Anna's Archive direct download fails (zero slow URLs or all links
exhausted), atomically fall back to indexer search with a single DB-
backed claim to prevent duplicate fallback loops. Fallback searches
skip Anna and use the existing protocol routing (qBittorrent for torrents,
SABnzbd for usenet).

When a ranked ebook candidate permanently fails at either the
add-to-client handoff or the monitor/download stage, blocklist that
release for the request and automatically continue to the next ranked
candidate until one succeeds or candidates are exhausted. Transient
connection failures remain retryable and do not trigger fallback.

Behavior details:
- DB-backed atomic claim prevents race conditions on retry
- Request-scoped blocklist excludes previously failed releases
- Audiobook requests unchanged
- search_attempts not double-counted
- Fallback search is marked with isFallback=true

Production-tested on A Day of Fallen Night requests showing multiple
fallback transitions across Anna, torrent add-failure, and SAB monitor-
stage failures.

Tests added:
- Anna fallback atomicity and claim behavior
- Zero URLs and exhausted-links coverage
- Ranked continuation after add-to-client failures
- Monitor-stage continuation failures
- Transient vs permanent failure distinction
- Exhaustion behavior
Refactors download failure handling to support atomic fallback from direct
download to indexer search and ranked-hierarchy continuation through search
candidates. Applies ranked continuation to both ebooks and audiobooks while
preserving transient/permanent error semantics.

Key changes:
- Introduce direct-download-fallback.ts for atomic fallback enqueuing
- Replace anna-prowlarr-fallback.ts with generic direct-download-fallback
- Add isFallback flag to search_ebook processor to skip direct download sources
- Extend ranked-hierarchy continuation to audiobooks (previously ebooks only)
- Maintain transient/permanent error distinction in both processors
- Ensure no double-counting of searchAttempts

Files changed:
- src/lib/processors/direct-download.processor.ts: call generic fallback helper
- src/lib/processors/download-torrent.processor.ts: rank-continuation for both types
- src/lib/processors/monitor-download.processor.ts: lowercase messages, audiobooks continue
- src/lib/utils/direct-download-fallback.ts: new atomic fallback implementation
- src/lib/utils/anna-prowlarr-fallback.ts: deleted (replaced)
- tests/processors/direct-download.processor.test.ts: updated expectations
- tests/processors/download-torrent.processor.test.ts: verify audiobook continuation
- tests/processors/monitor-download.processor.test.ts: lowercase message expectations
- tests/processors/direct-download-fallback.test.ts: new generic fallback tests
- tests/processors/ranked-continuation-audiobooks.test.ts: audiobook continuation tests
- tests/processors/anna-prowlarr-fallback.test.ts: deleted (replaced)
- tests/processors/ranked-continuation-ebooks.test.ts: deleted (covered by generic tests)

Verification:
- npm exec prisma generate: PASSED
- npx tsc --noEmit: PASSED
- npm run test: 2596 passed, 4 skipped, 0 failed (full suite green)
- npm run build: PASSED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant