Wait for all tasks to finish or until the timeout is reached. Args: tasks: A sequence of asyncio tasks to wait for. logger: Logger to use for reporting. timeout: How long should we wait before cancelling the tasks.
(
tasks: Sequence[asyncio.Task],
*,
logger: Logger,
timeout: timedelta | None = None,
)
| 47 | |
| 48 | |
| 49 | async def wait_for_all_tasks_for_finish( |
| 50 | tasks: Sequence[asyncio.Task], |
| 51 | *, |
| 52 | logger: Logger, |
| 53 | timeout: timedelta | None = None, |
| 54 | ) -> None: |
| 55 | """Wait for all tasks to finish or until the timeout is reached. |
| 56 | |
| 57 | Args: |
| 58 | tasks: A sequence of asyncio tasks to wait for. |
| 59 | logger: Logger to use for reporting. |
| 60 | timeout: How long should we wait before cancelling the tasks. |
| 61 | """ |
| 62 | if not tasks: |
| 63 | return |
| 64 | |
| 65 | timeout_secs = timeout.total_seconds() if timeout else None |
| 66 | try: |
| 67 | _, pending = await asyncio.wait(tasks, timeout=timeout_secs) |
| 68 | if pending: |
| 69 | logger.warning('Waiting timeout reached; canceling unfinished tasks.') |
| 70 | except asyncio.CancelledError: |
| 71 | logger.warning('Asyncio wait was cancelled; canceling unfinished tasks.') |
| 72 | raise |
| 73 | finally: |
| 74 | for task in tasks: |
| 75 | if not task.done(): |
| 76 | task.cancel() |
| 77 | with suppress(asyncio.CancelledError): |
| 78 | await task |
| 79 | # If task is done, access the result to clear any exceptions |
| 80 | else: |
| 81 | try: |
| 82 | task.result() |
| 83 | except asyncio.CancelledError: |
| 84 | pass |
| 85 | except Exception as e: |
| 86 | logger.warning(f'Task raised an exception: {e}') |
no outgoing calls
no test coverage detected