Add per-provider fallback threshold for download services - #3
Open
Gabriel-Lewis wants to merge 1 commit into
Open
Add per-provider fallback threshold for download services#3Gabriel-Lewis wants to merge 1 commit into
Gabriel-Lewis wants to merge 1 commit into
Conversation
DOWNLOAD_SERVICES is already documented as an ordered priority list, and
StartDownload already skips tracks an earlier provider resolved:
for _, d := range c.Downloaders {
for _, track := range *tracks {
if track.Present { continue }
What was missing is a time budget. MonitorDownloads only returns once
tracksProcessed() reports every track Present or Skipped, and the
per-track MonitorDuration stall timer resets on any byte of progress. A
provider that keeps making slow progress therefore holds the whole run,
and the next service never gets a turn.
Add MonitorConfig.FallbackAfter, sourced per provider from
SLSKD_FALLBACK_AFTER / LIDARR_FALLBACK_AFTER (minutes, default 0 =
disabled, preserving current behaviour). When the budget elapses,
MonitorDownloads abandons the still-unresolved tracks and returns, and
the existing track.Present skip logic hands them to the next provider.
Abandoning calls Cleanup on each unresolved track so the provider stops
downloading in the background once we have moved on -- Lidarr.Cleanup
DELETEs the queue item with removeFromClient=true, and Slskd.Cleanup
removes the search and transfer. Without this, giving up on a provider
would leave orphaned downloads running.
This makes chains like the following work as intended -- prefer full
albums from Lidarr, fall back to slskd for whatever it has not delivered:
DOWNLOAD_SERVICES=lidarr,slskd
LIDARR_FALLBACK_AFTER=15
SLSKD_FALLBACK_AFTER=10
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ZuEbqv1CGbPub9kB3g2s4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #2 (Lidarr) — base is
feat/lidarr, so this PR shows only its own diff.The gap
DOWNLOAD_SERVICESis already an ordered priority list (sample.envhas said so all along), andStartDownloadalready skips tracks an earlier provider resolved:So ordering and "only try what is still missing" work today. What was missing is a time budget.
MonitorDownloadsonly returns oncetracksProcessed()reports every trackPresentorSkipped, and the per-trackMonitorDurationstall timer resets on any byte of progress — so a provider making slow progress holds the entire run and the next service never gets a turn.The change
MonitorConfiggainsFallbackAfter, sourced per provider fromSLSKD_FALLBACK_AFTER/LIDARR_FALLBACK_AFTER(minutes, default0= disabled, so existing setups behave exactly as before). When the budget elapses,MonitorDownloadsabandons the unresolved tracks and returns; the existingtrack.Presentskip logic hands them to the next provider.Abandoning calls
Cleanupon each unresolved track so the provider stops downloading in the background once we have moved on —Lidarr.CleanupDELETEs the queue item withremoveFromClient=true,Slskd.Cleanupremoves the search and transfer. Without that, giving up would leave orphaned downloads running.YouTube is untouched: it is synchronous and its
GetConf()already returns an error signalling no monitoring.Worked example
Tier 0 remains the existing library check (
CheckTracks), which already skips anything Plex/Jellyfin/etc. already has — so the full chain is: already in library → Lidarr full albums → slskd.Verified
go build ./src/main/andgo vet ./src/downloader/ ./src/config/— both clean.gofmt: no new unformatted files; the one flagged line inslskd.gosits inside a struct literal that was already misaligned upstream, and matches its neighbours.Not exercised against a live Lidarr/slskd run; the runtime check is described below.
How to test
Set
LIDARR_FALLBACK_AFTER=1to force the path quickly, run, and confirm:[monitor] fallback threshold reached, moving on to the next download service service=LidarrCleanupfired)