feat: queue de téléchargement séquentielle (un à la fois)
Docker / docker (push) Successful in 1m38s

asyncio.Queue dans DownloadManager + worker unique démarré dans le lifespan.
Les téléchargements s'exécutent un par un dans l'ordre d'arrivée.
Suppression de BackgroundTasks (plus nécessaire).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dev
2026-05-03 11:30:07 +02:00
parent a4ffd6d63e
commit a4273557ad
2 changed files with 19 additions and 29 deletions
+9 -20
View File
@@ -8,7 +8,6 @@ from datetime import datetime
from pathlib import Path
import yt_dlp
from fastapi import BackgroundTasks
OUTPUT_DIR = "/data/Arte"
DB_PATH = "data/arte_dl.db"
@@ -87,6 +86,7 @@ class DownloadManager:
def __init__(self):
self._active: dict[str, dict] = {}
self._lock = threading.Lock()
self._queue: asyncio.Queue = asyncio.Queue()
self._init_db()
def _init_db(self):
@@ -147,7 +147,8 @@ class DownloadManager:
).fetchone()
return row is not None
def _insert_queued(self, url: str, title: str) -> str:
async def enqueue(self, url: str, title: str, subtitle: str,
year: int | None, category: str) -> str:
dl_id = str(uuid.uuid4())
now = datetime.now().isoformat()
with _db() as conn:
@@ -157,20 +158,15 @@ class DownloadManager:
)
with self._lock:
self._active[dl_id] = {"state": "queued", "progress": 0, "title": title}
await self._queue.put((dl_id, url, title, subtitle, year, category))
return dl_id
def enqueue(self, url: str, title: str, subtitle: str, year: int | None,
category: str, bg: BackgroundTasks) -> str:
dl_id = self._insert_queued(url, title)
bg.add_task(self._run, dl_id, url, title, subtitle, year, category)
return dl_id
async def enqueue_direct(self, url: str, title: str, subtitle: str,
year: int | None, category: str) -> str:
dl_id = self._insert_queued(url, title)
async def start_worker(self):
loop = asyncio.get_running_loop()
loop.run_in_executor(None, self._run, dl_id, url, title, subtitle, year, category)
return dl_id
while True:
job = await self._queue.get()
dl_id, url, title, subtitle, year, category = job
await loop.run_in_executor(None, self._run, dl_id, url, title, subtitle, year, category)
def status(self, dl_id: str) -> dict:
with self._lock:
@@ -183,13 +179,6 @@ class DownloadManager:
).fetchall()
return [dict(r) for r in rows]
def already_downloaded(self, url: str) -> bool:
with _db() as conn:
row = conn.execute(
"SELECT id FROM downloads WHERE url=? AND state='done' LIMIT 1", (url,)
).fetchone()
return row is not None
# ----------------------------------------------------------------- private
def _set(self, dl_id: str, **kw):