"""Постановка задач ARQ worker'у из API. Пул Redis создаётся лениво при первой задаче, а не в lifespan: недоступный Redis не должен ронять старт API. Если задачу поставить не удалось, чек остаётся `pending`, и cron `poll_receipts` подхватит его в течение минуты. """ from __future__ import annotations from typing import Any, Protocol from arq import ArqRedis, create_pool from arq.connections import RedisSettings from app.core.config import settings from app.core.logging import get_logger log = get_logger(__name__) class TaskQueue(Protocol): async def enqueue(self, function: str, *args: Any) -> None: ... class ArqTaskQueue: def __init__(self) -> None: self._pool: ArqRedis | None = None async def enqueue(self, function: str, *args: Any) -> None: try: if self._pool is None: self._pool = await create_pool( RedisSettings.from_dsn(settings.redis_url), retry=0 ) await self._pool.enqueue_job(function, *args) except Exception as exc: # noqa: BLE001 — см. докстринг модуля log.warning("enqueue_failed", function=function, error=repr(exc)) async def close(self) -> None: if self._pool is not None: await self._pool.aclose() self._pool = None _queue = ArqTaskQueue() def get_task_queue() -> TaskQueue: return _queue async def close_task_queue() -> None: await _queue.close()