From d465198c4ac7cc147f2bd1fc290de2c1b0340695 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Fri, 6 Nov 2026 22:15:26 -0500 Subject: [PATCH] fix: the media backup task has its own stall threshold, and its test seeds a post for a shared archive Co-Authored-By: Claude Opus 5.5 --- backend/app/tasks/maintenance.py | 3 +++ tests/test_backup_media.py | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/backend/app/tasks/maintenance.py b/backend/app/tasks/maintenance.py index 572d667..74c902e 100644 --- a/backend/app/tasks/maintenance.py +++ b/backend/app/tasks/maintenance.py @@ -173,6 +173,9 @@ TASK_STUCK_THRESHOLD_MINUTES: dict[str, int] = { # legitimately-running backup isn't flagged. "backend.app.tasks.backup.backup_images_task": 420, "backend.app.tasks.backup.restore_images_task": 420, + # One media-backup chunk stops starting files after 45 min but may finish + # a large file in flight, up to its 6.5 h hard limit. + "backend.app.tasks.backup.backup_media_task": 420, # Library audit scans the full library — 2h hard limit. "backend.app.tasks.library_audit.scan_library_for_rule": 130, # External file-host fetches (mega/gdrive/film packs) can run to the task's diff --git a/tests/test_backup_media.py b/tests/test_backup_media.py index 60c4c69..940e60b 100644 --- a/tests/test_backup_media.py +++ b/tests/test_backup_media.py @@ -7,7 +7,14 @@ from datetime import UTC, datetime, timedelta import pytest from sqlalchemy import select -from backend.app.models import BackupBlob, BackupRun, ImageRecord, PostAttachment +from backend.app.models import ( + Artist, + BackupBlob, + BackupRun, + ImageRecord, + Post, + PostAttachment, +) from backend.app.services import backup_media from backend.app.services.backup_s3 import ListPage, S3Error, S3Target, StoredObject @@ -51,8 +58,15 @@ def test_the_work_list_is_every_file_once_that_the_bucket_lacks(db_sync, tmp_pat _image(db_sync, tmp_path, "a") _image(db_sync, tmp_path, "b") _attachment(db_sync, tmp_path, "c") - # The same archive held by a second post is one file to send. - db_sync.add(PostAttachment(sha256=_sha("c"), path=str(tmp_path / "c-copy.zip"), + # The same archive held by a post as well is one file to send. + artist = Artist(name="Bea", slug="bea") + db_sync.add(artist) + db_sync.flush() + post = Post(artist_id=artist.id, external_post_id="p1") + db_sync.add(post) + db_sync.flush() + db_sync.add(PostAttachment(post_id=post.id, sha256=_sha("c"), + path=str(tmp_path / "c-copy.zip"), original_filename="set.zip", ext=".zip", size_bytes=3)) db_sync.add(BackupBlob(target=TID, sha256=_sha("b"), key="media/bb", size_bytes=3)) # A row for another bucket doesn't count for this one.