RICS / app /api /background_tasks.py
StormShadow308's picture
feat: async pipeline, job queue, generation hardening, and docs
732b14f
Raw
History Blame Contribute Delete
1.01 kB
"""Shared asyncio task registry so background jobs are not garbage-collected."""
from __future__ import annotations
import asyncio
import logging
logger = logging.getLogger(__name__)
_background_tasks: set[asyncio.Task] = set() # type: ignore[type-arg]
def _log_task_outcome(task: asyncio.Task) -> None: # type: ignore[type-arg]
"""Surface exceptions from fire-and-forget tasks (handlers should still catch)."""
try:
exc = task.exception()
except asyncio.CancelledError:
return
if exc is not None:
logger.error(
"Unhandled exception in background task: %s",
exc,
exc_info=exc,
)
def spawn_background_task(coro) -> asyncio.Task: # type: ignore[no-untyped-def]
"""Schedule ``coro`` and retain the task until it completes."""
task = asyncio.create_task(coro)
_background_tasks.add(task)
task.add_done_callback(_background_tasks.discard)
task.add_done_callback(_log_task_outcome)
return task