From e0ba21eb07dc79178b524e559985ed06d95938f6 Mon Sep 17 00:00:00 2001 From: fchinembiri Date: Sat, 11 Jul 2026 22:09:38 +0200 Subject: [PATCH] fix(musicseerr): implement thread-safe jobs saving with a write lock and unique temp files --- apps/musicseerr/main.py | 18 +++++++++++------- apps/musicseerr/tasks.py | 19 ++++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/apps/musicseerr/main.py b/apps/musicseerr/main.py index c025ad5..fc09559 100644 --- a/apps/musicseerr/main.py +++ b/apps/musicseerr/main.py @@ -19,14 +19,18 @@ import json JOBS_FILE = "/remote-music/.musicseerr_jobs.json" +from tasks import JOBS_WRITE_LOCK + def save_jobs_db(jobs_dict): - try: - temp_file = JOBS_FILE + ".tmp" - with open(temp_file, "w") as f: - json.dump(jobs_dict, f, indent=2) - os.replace(temp_file, JOBS_FILE) - except Exception as e: - logger.error(f"Failed to save jobs database: {e}") + with JOBS_WRITE_LOCK: + try: + temp_file = f"{JOBS_FILE}.{uuid.uuid4()}.tmp" + with open(temp_file, "w") as f: + json.dump(jobs_dict, f, indent=2) + os.replace(temp_file, JOBS_FILE) + except Exception as e: + logger.error(f"Failed to save jobs database: {e}") + def load_jobs_db(): if os.path.exists(JOBS_FILE): diff --git a/apps/musicseerr/tasks.py b/apps/musicseerr/tasks.py index 1e5f1b6..7953c60 100644 --- a/apps/musicseerr/tasks.py +++ b/apps/musicseerr/tasks.py @@ -20,14 +20,19 @@ logger = logging.getLogger("musicseerr-tasks") JOBS_FILE = "/remote-music/.musicseerr_jobs.json" +JOBS_WRITE_LOCK = threading.Lock() + def save_jobs(jobs_dict): - try: - temp_file = JOBS_FILE + ".tmp" - with open(temp_file, "w") as f: - json.dump(jobs_dict, f, indent=2) - os.replace(temp_file, JOBS_FILE) - except Exception as e: - logger.error(f"Failed to save jobs database: {e}") + with JOBS_WRITE_LOCK: + try: + import uuid + temp_file = f"{JOBS_FILE}.{uuid.uuid4()}.tmp" + with open(temp_file, "w") as f: + json.dump(jobs_dict, f, indent=2) + os.replace(temp_file, JOBS_FILE) + except Exception as e: + logger.error(f"Failed to save jobs database: {e}") + def move_new_files_to_dest(temp_dir: str, dest_dir: str) -> list: moved = []