Fix: make the global media lock reentrant within a thread

Every caller built its own FileLock on media.lock, so code already holding it could not call into code that takes it again without blocking itself. That made it impossible to take media.lock before opening a transaction in paths that also attach files or move files inside that transaction.

media_lock() hands out one FileLock instance per path with per-thread hold counts, so a thread re-enters while other threads and processes stay excluded. All media.lock call sites now use it.
This commit is contained in:
stumpylog committed 2026-11-09 12:25:21 -08:00
1 parent f9d0a58a41
commit 26e513fbd1
10 files changed
+252 -15

No files matched your search

+2 -2
View File
@@ -16,7 +16,6 @@ from django.db import models
from django.db import transaction
from django.db.models.signals import post_save
from django.utils import timezone
from filelock import FileLock
from documents import sanity_checker
from documents.barcodes import BarcodePlugin
@@ -42,6 +41,7 @@ from documents.double_sided import CollatePlugin
from documents.file_handling import create_source_path_directory
from documents.file_handling import generate_unique_filename
from documents.matching import prefilter_documents_by_workflowtrigger
from documents.media_lock import media_lock
from documents.models import Correspondent
from documents.models import CustomFieldInstance
from documents.models import Document
@@ -482,7 +482,7 @@ def update_document_content_maybe_archive_file(
modified=timezone.now(),
)
with FileLock(settings.MEDIA_LOCK):
with media_lock():
if parser.get_archive_path():
create_source_path_directory(document.archive_path)
shutil.move(parser.get_archive_path(), document.archive_path)