fix(downloads): force IPv4 (fixes container 'Errno -5' DNS failures) + retry resets errored asset

Root cause of the failing downloads: containers usually have no working IPv6 route, but
googlevideo CDN hosts advertise AAAA records, so the downloader tried IPv6 and failed with
'[Errno -5] No address associated with hostname'. Small clips happened to use IPv4; long videos
(more CDN requests / the ffmpeg path) hit IPv6 and died.
- yt-dlp source_address=0.0.0.0 forces IPv4 for every connection (== --force-ipv4). Verified: the
  full video+audio download completes cleanly.
- Also: retry (resume) now resets the shared asset from 'error' to 'pending', so it actually
  re-downloads — previously the requeued job instantly re-inherited the asset's stale error
  because the worker short-circuits a job whose asset already errored.
- Dropped the localdev DNS override (wrong hypothesis; the issue was IPv6, not the resolver).
- Kept yt-dlp retries/fragment_retries/socket_timeout for transient blips.

Verified end-to-end in the worker: two previously-failing long videos now download to done.
This commit is contained in:
npeter83 2026-07-03 03:47:13 +02:00
parent 7ae19c2f8d
commit 4b15d55092
2 changed files with 18 additions and 3 deletions

View file

@ -364,6 +364,14 @@ def resume_download(
if job.status in ("paused", "error"):
job.progress = 0
job.error = None
# If the shared asset itself failed, reset it to pending so the worker actually
# re-downloads — otherwise the requeued job would instantly re-inherit the asset's
# stale error (the worker short-circuits a job whose asset is already errored).
if job.asset_id:
asset = db.get(MediaAsset, job.asset_id)
if asset and asset.status == "error":
asset.status = "pending"
asset.error = None
_set_status(db, job, "queued")
asset = db.get(MediaAsset, job.asset_id) if job.asset_id else None
return _serialize(job, asset)