Fix queue worker failure handling and thumbnail fallbacks
This commit is contained in:
+48
-10
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user