ingest: retry transient HTTP connection errors

Give the outgoing HTTP clients (Navidrome, MusicBrainz, ListenBrainz) a
transport-level retry budget (RADIEO_HTTP_RETRIES, default 2) so a brief
connection blip on a remote endpoint no longer drops a fetch or a lookup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
nemunaire 2026-07-02 22:47:13 +08:00
commit d486558883
4 changed files with 13 additions and 1 deletions

View file

@ -32,6 +32,7 @@ class Canonicalizer:
timeout=httpx.Timeout(connect=10.0, read=30.0, write=10.0, pool=10.0),
headers={"User-Agent": config.USER_AGENT},
follow_redirects=True,
transport=httpx.HTTPTransport(retries=config.HTTP_RETRIES),
)
self._rate_lock = threading.Lock()
self._last_call = 0.0

View file

@ -18,6 +18,10 @@ STATE_DB = STATE_DIR / "radieo.db"
HTTP_HOST = os.environ.get("RADIEO_HTTP_HOST", "0.0.0.0")
HTTP_PORT = int(os.environ.get("RADIEO_HTTP_PORT", "8080"))
# Transport-level retries for transient connection errors on outgoing HTTP
# (Navidrome, MusicBrainz, ListenBrainz). Applies to connect failures only.
HTTP_RETRIES = int(os.environ.get("RADIEO_HTTP_RETRIES", "2"))
# --- Prefetching / retention ---
# How many downloaded tracks to keep ready ahead of playback.
PREFETCH = int(os.environ.get("RADIEO_PREFETCH", "3"))

View file

@ -66,6 +66,7 @@ class ListenBrainzProvider:
timeout=httpx.Timeout(connect=10.0, read=30.0, write=10.0, pool=10.0),
headers={"User-Agent": config.USER_AGENT},
follow_redirects=True,
transport=httpx.HTTPTransport(retries=config.HTTP_RETRIES),
)
self._recs: list[dict] = []
self._loaded_at = 0.0

View file

@ -11,6 +11,8 @@ from pathlib import Path
import httpx
from . import config
log = logging.getLogger("radieo.subsonic")
# Advertised API version and client name.
@ -43,7 +45,11 @@ class SubsonicClient:
self._base = base_url.rstrip("/")
self._user = user
self._password = password
self._http = httpx.Client(timeout=30.0, follow_redirects=True)
self._http = httpx.Client(
timeout=30.0,
follow_redirects=True,
transport=httpx.HTTPTransport(retries=config.HTTP_RETRIES),
)
def _auth_params(self) -> dict[str, str]:
salt = secrets.token_hex(8)