Spaces:
Sleeping
Sleeping
File size: 1,007 Bytes
732b14f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | """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
|