Files
zpan/cmd/internal
Jasper VanandClaude Opus 4.8 64b0ea3e81 fix(downloader): give seeding its own concurrency budget and recycle orphan seeds (#462)
Two coupled bugs starved aria2 downloads on long-running nodes.

Concurrency: max_concurrent_tasks is the download budget only, but aria2
counts seeding torrents as active downloads, so retained seeds were eating
the shared --max-concurrent-downloads (default 5) and new downloads queued
forever in 'waiting' with no error. Seeding now gets its own budget via a new
Downloader-local config downloader.seed.max_concurrent (default 10); aria2's
--max-concurrent-downloads is set to max_concurrent_tasks + that budget, so
seeds can never consume a download slot. The worker still caps real download
concurrency itself.

Orphan seeds: aria2 was told SeedTime=1000000 (~694 days), so it never
stopped seeding on its own; the worker was the sole authority, and any drift
between aria2's session and the worker's ledger (e.g. across restarts) left
torrents seeding forever, holding slots and disk, never expired. Two fixes:
- aria2 SeedTime is now the configured seed_duration (+ seed-ratio), so aria2
  stops seeding on its own even if the worker loses track.
- The worker reconciles on startup and periodically: any torrent the engine
  is still seeding but the worker no longer tracks is adopted into the ledger
  with an expiry (skipping in-flight/already-tracked tasks), so normal
  time/ratio/cache cleanup applies instead of leaking.

Adds SeedLister + aria2 ListSeeds. Tests cover the new config, aria2 args,
seed-time mapping, and orphan adoption (skipping running/tracked tasks).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 02:09:36 -04:00
..