"""Enqueue helper — submit a job to the arq queue from the request cycle. A short-lived pool per call keeps things simple (enqueues are rare, admin-driven actions). Redis being down degrades to a clean 503 rather than a crash (graceful degradation).""" from typing import Any from arq import create_pool from arq.connections import RedisSettings from app.core.config import get_settings from app.domain.errors import DependencyUnavailableError async def enqueue(function: str, **kwargs: Any) -> str: """Enqueue ``function`` by name, returning the job id. Raises :class:`DependencyUnavailableError` if the queue can't be reached.""" settings = get_settings() try: pool = await create_pool(RedisSettings.from_dsn(str(settings.redis_url))) except Exception as exc: raise DependencyUnavailableError("Task queue (Redis) is unavailable.") from exc try: job = await pool.enqueue_job(function, **kwargs) finally: await pool.aclose() if job is None: raise DependencyUnavailableError("Could not enqueue job.") return str(job.job_id)