Implement async series data loading with background processing

- Add loading status fields to AnimeSeries model
- Create BackgroundLoaderService for async task processing
- Update POST /api/anime/add to return 202 Accepted immediately
- Add GET /api/anime/{key}/loading-status endpoint
- Integrate background loader with startup/shutdown lifecycle
- Create database migration script for loading status fields
- Add unit tests for BackgroundLoaderService (10 tests, all passing)
- Update AnimeSeriesService.create() to accept loading status fields

Architecture follows clean separation with no code duplication:
- BackgroundLoader orchestrates, doesn't reimplement
- Reuses existing AnimeService, NFOService, WebSocket patterns
- Database-backed status survives restarts
This commit is contained in:
2026-01-19 07:14:55 +01:00
parent df19f8ad95
commit f18c31a035
12 changed files with 3463 additions and 141 deletions

View File

@@ -65,6 +65,11 @@ class AnimeSeriesService:
site: str,
folder: str,
year: int | None = None,
loading_status: str = "completed",
episodes_loaded: bool = True,
logo_loaded: bool = False,
images_loaded: bool = False,
loading_started_at: datetime | None = None,
) -> AnimeSeries:
"""Create a new anime series.
@@ -75,6 +80,11 @@ class AnimeSeriesService:
site: Provider site URL
folder: Local filesystem path
year: Release year (optional)
loading_status: Initial loading status (default: "completed")
episodes_loaded: Whether episodes are loaded (default: True for backward compat)
logo_loaded: Whether logo is loaded (default: False)
images_loaded: Whether images are loaded (default: False)
loading_started_at: When loading started (optional)
Returns:
Created AnimeSeries instance
@@ -88,6 +98,11 @@ class AnimeSeriesService:
site=site,
folder=folder,
year=year,
loading_status=loading_status,
episodes_loaded=episodes_loaded,
logo_loaded=logo_loaded,
images_loaded=images_loaded,
loading_started_at=loading_started_at,
)
db.add(series)
await db.flush()