Fix download cleanup after wishlist runs

- ignore unconfigured backends when clearing completed downloads
- keep the post-download cleanup route best-effort after a successful wishlist run
- add regression coverage for the orchestrator clear step
pull/400/head
Antti Kettunen 4 weeks ago
parent a7c1bb96a1
commit f75c180cb6
No known key found for this signature in database
GPG Key ID: C6B2A3D250359BD7

@ -457,12 +457,25 @@ class DownloadOrchestrator:
True if successful
"""
results = []
for client in [self.soulseek, self.youtube, self.tidal, self.qobuz, self.hifi, self.deezer_dl, self.lidarr]:
if client:
try:
results.append(await client.clear_all_completed_downloads())
except Exception:
pass
for name, client in [
("soulseek", self.soulseek),
("youtube", self.youtube),
("tidal", self.tidal),
("qobuz", self.qobuz),
("hifi", self.hifi),
("deezer_dl", self.deezer_dl),
("lidarr", self.lidarr),
]:
if not client:
continue
if hasattr(client, "is_configured") and not client.is_configured():
logger.debug("Skipping %s clear_all_completed_downloads (not configured)", name)
continue
try:
results.append(await client.clear_all_completed_downloads())
except Exception as exc:
logger.warning("%s clear_all_completed_downloads failed: %s", name, exc)
results.append(False)
return all(results) if results else True

@ -0,0 +1,61 @@
from core.download_orchestrator import DownloadOrchestrator
class _FakeClient:
def __init__(self, configured=True, clear_result=True):
self.configured = configured
self.clear_result = clear_result
self.clear_calls = 0
def is_configured(self):
return self.configured
async def clear_all_completed_downloads(self):
self.clear_calls += 1
return self.clear_result
def _build_orchestrator(**clients):
orch = DownloadOrchestrator.__new__(DownloadOrchestrator)
orch.soulseek = clients.get("soulseek")
orch.youtube = clients.get("youtube")
orch.tidal = clients.get("tidal")
orch.qobuz = clients.get("qobuz")
orch.hifi = clients.get("hifi")
orch.deezer_dl = clients.get("deezer_dl")
orch.lidarr = clients.get("lidarr")
return orch
def _run_async(coro):
import asyncio
loop = asyncio.new_event_loop()
try:
return loop.run_until_complete(coro)
finally:
loop.close()
def test_clear_all_completed_downloads_ignores_unconfigured_clients():
orch = _build_orchestrator(
soulseek=_FakeClient(configured=True, clear_result=True),
youtube=_FakeClient(configured=False, clear_result=False),
)
result = _run_async(orch.clear_all_completed_downloads())
assert result is True
assert orch.soulseek.clear_calls == 1
assert orch.youtube.clear_calls == 0
def test_clear_all_completed_downloads_propagates_configured_failures():
orch = _build_orchestrator(
soulseek=_FakeClient(configured=True, clear_result=False),
)
result = _run_async(orch.clear_all_completed_downloads())
assert result is False
assert orch.soulseek.clear_calls == 1

@ -20583,6 +20583,7 @@ def _build_master_deps():
)
def _run_full_missing_tracks_process(batch_id, playlist_id, tracks_json):
return _downloads_master.run_full_missing_tracks_process(
batch_id, playlist_id, tracks_json, _build_master_deps()

Loading…
Cancel
Save