"""arq task functions. Thin wrappers around the ingestion runner so retry/ concurrency/observability behavior lives in arq's worker loop, not here. Each task receives the `IngestionJob` row's id (created synchronously by the enqueuing endpoint via `get_or_create_ingestion_job`, *not* generated here) so status polling has a real, immediately-valid id to look up from the moment the HTTP response comes back. """ from __future__ import annotations import uuid from typing import Any from app.core.logging import get_logger from app.services.ingestion.runner import ( get_or_create_ingestion_job, get_series_season_numbers, run_movie_ingestion, run_person_ingestion, run_season_ingestion, run_series_ingestion, ) logger = get_logger(__name__) async def ingest_movie_task(ctx: dict[str, Any], job_id: str, external_id: str) -> str: movie_id = await run_movie_ingestion(uuid.UUID(job_id), external_id) return str(movie_id) async def ingest_person_task(ctx: dict[str, Any], job_id: str, external_id: str) -> str: person_id = await run_person_ingestion(uuid.UUID(job_id), external_id) return str(person_id) async def ingest_series_task( ctx: dict[str, Any], job_id: str, external_id: str, include_seasons: bool = False ) -> str: series_id = await run_series_ingestion(uuid.UUID(job_id), external_id) if include_seasons: # Fan out one ingest_season job per season this series has, using # the same arq connection this task is running on (arq hands every # job's ctx a "redis" entry precisely for chaining/fan-out like # this) — not a second, unrelated connection. redis = ctx["redis"] for season_number in await get_series_season_numbers(series_id): season_job_id = await get_or_create_ingestion_job( "season_sync", "season", f"{external_id}:{season_number}" ) await redis.enqueue_job( "ingest_season_task", str(season_job_id), external_id, season_number ) logger.info( "series_seasons_cascaded", series_id=str(series_id), external_id=external_id ) return str(series_id) async def ingest_season_task( ctx: dict[str, Any], job_id: str, series_external_id: str, season_number: int ) -> str: season_id = await run_season_ingestion(uuid.UUID(job_id), series_external_id, season_number) return str(season_id)