Spaces:
Runtime error
Runtime error
| """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 | |