| 24 | |
| 25 | |
| 26 | async def close_runners(runners: List[Runner]) -> None: |
| 27 | cleanup_tasks = [asyncio.create_task(runner.close()) for runner in runners] |
| 28 | if cleanup_tasks: |
| 29 | # Wait for all cleanup tasks with timeout |
| 30 | done, pending = await asyncio.wait( |
| 31 | cleanup_tasks, |
| 32 | timeout=30.0, # 30 second timeout for cleanup |
| 33 | return_when=asyncio.ALL_COMPLETED, |
| 34 | ) |
| 35 | |
| 36 | # If any tasks are still pending, log it |
| 37 | if pending: |
| 38 | logger.warning( |
| 39 | "%s runner close tasks didn't complete in time", len(pending) |
| 40 | ) |
| 41 | for task in pending: |
| 42 | task.cancel() |