Fix queue worker failure handling and thumbnail fallbacks

This commit is contained in:
Dymas
2026-05-16 11:02:18 +02:00
parent 0194476b33
commit 92762b07d5
7 changed files with 181 additions and 17 deletions
+48 -10
View File
@@ -5,6 +5,7 @@
import concurrent.futures
import json
import os
import shutil
import signal
import sqlite3
import subprocess
@@ -740,6 +741,33 @@ class DownloadQueue:
if should_flush:
self._save_job_locked(job)
def _cleanup_staging_dir(self, job):
staging_dir = job_staging_dir(job)
if not staging_dir.exists():
return False
try:
shutil.rmtree(staging_dir)
debug_log("queue.cleanup.staging_removed", job_id=job.get("id"), staging_dir=staging_dir)
return True
except OSError as exc:
debug_log("queue.cleanup.staging_failed", job_id=job.get("id"), staging_dir=staging_dir, error=exc)
return False
def _fail_job_startup(self, job, exc):
message = f"Could not start download: {exc}"
with self.lock:
job["status"] = "failed"
job["exit_code"] = 1
job["pid"] = None
job["finished_at"] = now_iso()
job["updated_at"] = job["finished_at"]
job.setdefault("log", []).append(message)
self.current_process = None
self.current_job_id = None
self.current_job = None
self._save_job_locked(job)
self._cleanup_staging_dir(job)
def _run(self):
while not self.stop_event.is_set():
job = self._next_pending()
@@ -781,16 +809,20 @@ class DownloadQueue:
job["_dirty_log_lines"] = 0
self._save_job_locked(job)
process = subprocess.Popen(
command,
cwd=str(PROJECT_ROOT),
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
start_new_session=True,
)
try:
process = subprocess.Popen(
command,
cwd=str(PROJECT_ROOT),
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
bufsize=1,
start_new_session=True,
)
except Exception as exc:
self._fail_job_startup(job, exc)
return
with self.lock:
self.current_process = process
self.current_job_id = job["id"]
@@ -805,6 +837,7 @@ class DownloadQueue:
finalize_error = None
moved_files = []
watchlist_sync_error = None
cleanup_staging = False
if exit_code == 0 and not job.get("cancel_requested"):
try:
moved_files = finalize_library_files(job)
@@ -841,7 +874,12 @@ class DownloadQueue:
else:
job["status"] = "failed"
job.setdefault("log", []).append(f"Download failed with exit code {exit_code}.")
cleanup_staging = True
if canceled:
cleanup_staging = True
self.current_process = None
self.current_job_id = None
self.current_job = None
self._save_job_locked(job)
if cleanup_staging:
self._cleanup_staging_dir(job)