soulsync/core/download_engine/__init__.py
Broque Thomas f40c6d3b55 B1: Add DownloadEngine skeleton
`core/download_engine/` package with the engine class that will own
cross-source state, threading, search retry, rate-limits, and
fallback chains. Orchestrator constructs an engine and registers
each plugin with it.

Phase B1 scope: skeleton only. Engine stores active_downloads
records keyed by (source, download_id), provides thread-safe
add/update/remove/iterate primitives, and holds plugin references
for later phases. NOT on any code path yet — pure additive
scaffolding so subsequent commits can introduce engine-driven
behavior one piece at a time without a big-bang switchover.

15 new tests pin the engine's state-storage contract: shallow-copy
reads, partial-patch updates, no-op-on-missing semantics,
per-source iteration, id-only find, concurrent-add safety.

Suite still 290 (download subset) green. Zero behavior change.
2026-05-04 12:39:41 -07:00

29 lines
1.2 KiB
Python

"""Download Engine — central owner of cross-source download state,
thread workers, search retry, rate-limits, and fallback chains.
This is the second leg of the multi-source download dispatcher
refactor (the first leg, ``core/download_plugins/``, defined the
contract). The engine takes ownership of everything that used to
be duplicated across the per-source clients (background thread
workers, active_downloads dicts, search retry ladders, quality
filtering, hybrid fallback). Clients become DUMB — just hit the
API for their source, manage their own auth state, and let the
engine drive everything else.
This package is built up in phases (see
``docs/download-engine-refactor-plan.md`` for the full plan):
- Phase B (current) — engine skeleton + state lift.
- Phase C — background download worker.
- Phase D — search retry + quality filter.
- Phase E — rate-limit pool.
- Phase F — fallback chain.
Each phase is purely additive at first (engine grows, clients
unchanged). Migration to the new shape happens one source per
commit so behavior never breaks across the suite.
"""
from core.download_engine.engine import DownloadEngine
__all__ = ["DownloadEngine"]