diff --git a/src/server/services/folder_scan_service.py b/src/server/services/folder_scan_service.py index c1e03e6..fc89fa0 100644 --- a/src/server/services/folder_scan_service.py +++ b/src/server/services/folder_scan_service.py @@ -129,6 +129,7 @@ async def perform_nfo_repair_scan(background_loader=None) -> None: queued = 0 total = 0 missing_nfo_count = 0 + repair_tasks: list[asyncio.Task] = [] for series_dir in sorted(anime_dir.iterdir()): if not series_dir.is_dir(): continue @@ -137,19 +138,31 @@ async def perform_nfo_repair_scan(background_loader=None) -> None: if not nfo_path.exists(): # Create minimal NFO for series without one missing_nfo_count += 1 - asyncio.create_task( - _create_missing_nfo(series_dir, series_name), - name=f"nfo_create:{series_name}", + repair_tasks.append( + asyncio.create_task( + _create_missing_nfo(series_dir, series_name), + name=f"nfo_create:{series_name}", + ) ) continue total += 1 if nfo_needs_repair(nfo_path): queued += 1 - asyncio.create_task( - _repair_one_series(series_dir, series_name), - name=f"nfo_repair:{series_name}", + repair_tasks.append( + asyncio.create_task( + _repair_one_series(series_dir, series_name), + name=f"nfo_repair:{series_name}", + ) ) + if repair_tasks: + logger.info( + "NFO repair scan: waiting for %d repair/create tasks to complete", + len(repair_tasks), + ) + await asyncio.gather(*repair_tasks, return_exceptions=True) + logger.info("NFO repair scan tasks completed") + logger.info( "NFO repair scan complete: %d of %d series queued for repair, %d missing NFOs queued for creation", queued, @@ -182,10 +195,10 @@ class FolderScanService: if not self._prerequisites_met(): return - # 1.3 — Repair incomplete NFO files in the background. + # 1.3 — Repair incomplete NFO files (synchronous, waits for completion). logger.info("Starting NFO repair scan as part of folder scan") await perform_nfo_repair_scan(background_loader=None) - logger.info("NFO repair scan queued; repairs will continue in background") + logger.info("NFO repair scan complete") # 1.4 — Validate and rename series folders after NFO repair. logger.info("Starting folder rename validation") diff --git a/tests/unit/test_initialization_service.py b/tests/unit/test_initialization_service.py index a1711cc..4f4479d 100644 --- a/tests/unit/test_initialization_service.py +++ b/tests/unit/test_initialization_service.py @@ -816,11 +816,14 @@ class TestPerformNfoRepairScan: return_value=mock_repair_service, ), patch( "asyncio.create_task" - ) as mock_create_task: + ) as mock_create_task, patch( + "asyncio.gather", new_callable=AsyncMock + ) as mock_gather: mock_factory_cls.return_value.create.return_value = MagicMock() await perform_nfo_repair_scan(background_loader=AsyncMock()) mock_create_task.assert_called_once() + mock_gather.assert_called_once() @pytest.mark.asyncio async def test_skips_complete_series(self, tmp_path): @@ -876,8 +879,11 @@ class TestPerformNfoRepairScan: return_value=mock_repair_service, ), patch( "asyncio.create_task" - ) as mock_create_task: + ) as mock_create_task, patch( + "asyncio.gather", new_callable=AsyncMock + ) as mock_gather: mock_factory_cls.return_value.create.return_value = MagicMock() await perform_nfo_repair_scan(background_loader=None) mock_create_task.assert_called_once() + mock_gather.assert_called_once()