mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-08-03 17:42:20 +00:00
Fix: don't re-queue a consume-folder file that is already queued and awaiting consumption (#13526)
This commit is contained in:
@@ -632,8 +632,20 @@ class Command(BaseCommand):
|
||||
# Process each change
|
||||
for change_type, path in changes:
|
||||
path = Path(path).resolve()
|
||||
if change_type == Change.deleted:
|
||||
# Consumed (or otherwise removed); a later file
|
||||
# reusing this name must not be skipped as
|
||||
# already-queued.
|
||||
queued.discard(path)
|
||||
if not path.is_file():
|
||||
continue
|
||||
if path in queued:
|
||||
# Already queued and awaiting consumption; a stray
|
||||
# event (NAS metadata touch, AV scan, etc.) while
|
||||
# the file sits on disk mid-consumption must not
|
||||
# cause it to be queued a second time (GH #13511).
|
||||
logger.debug(f"Ignoring event for queued file: {path}")
|
||||
continue
|
||||
logger.debug(f"Event: {change_type.name} for {path}")
|
||||
tracker.track(path, change_type)
|
||||
|
||||
|
||||
@@ -880,6 +880,41 @@ class TestCommandWatch:
|
||||
]
|
||||
assert call_args.original_file.name == "valid.pdf"
|
||||
|
||||
def test_ignores_event_for_already_queued_file(
|
||||
self,
|
||||
consumption_dir: Path,
|
||||
sample_pdf: Path,
|
||||
mock_consume_file_delay: MagicMock,
|
||||
start_consumer: Callable[..., ConsumerThread],
|
||||
) -> None:
|
||||
"""
|
||||
A stray filesystem event (NAS metadata touch, AV scan, etc.) on a
|
||||
file that has already been queued and is awaiting consumption must
|
||||
not cause it to be queued a second time (GH #13511). The task is
|
||||
mocked, so the file is never removed from disk, mirroring a
|
||||
long-running OCR job still holding it.
|
||||
"""
|
||||
thread = start_consumer()
|
||||
|
||||
target = consumption_dir / "document.pdf"
|
||||
shutil.copy(sample_pdf, target)
|
||||
|
||||
wait_for_mock_call(mock_consume_file_delay.apply_async, timeout_s=2.0)
|
||||
|
||||
if thread.exception:
|
||||
raise thread.exception
|
||||
|
||||
assert mock_consume_file_delay.apply_async.call_count == 1
|
||||
|
||||
# Simulate a stray event on the still-present, already-queued file.
|
||||
target.touch()
|
||||
sleep(0.5)
|
||||
|
||||
if thread.exception:
|
||||
raise thread.exception
|
||||
|
||||
assert mock_consume_file_delay.apply_async.call_count == 1
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.usefixtures("mock_supported_extensions")
|
||||
def test_stop_flag_stops_consumer(
|
||||
|
||||
Reference in New Issue
Block a user