关闭所有任务和资源
(self, timeout: float = 30.0)
| 56 | return resource |
| 57 | |
| 58 | async def shutdown(self, timeout: float = 30.0): |
| 59 | """关闭所有任务和资源""" |
| 60 | log.info("TaskManager shutdown initiated") |
| 61 | |
| 62 | # 设置关闭标志 |
| 63 | self._shutdown_event.set() |
| 64 | |
| 65 | # 取消所有未完成的任务 |
| 66 | cancelled_count = 0 |
| 67 | for task in list(self._tasks): |
| 68 | if not task.done(): |
| 69 | task.cancel() |
| 70 | cancelled_count += 1 |
| 71 | |
| 72 | if cancelled_count > 0: |
| 73 | log.info(f"Cancelled {cancelled_count} pending tasks") |
| 74 | |
| 75 | # 等待所有任务完成(包括取消) |
| 76 | if self._tasks: |
| 77 | try: |
| 78 | await asyncio.wait_for( |
| 79 | asyncio.gather(*self._tasks, return_exceptions=True), timeout=timeout |
| 80 | ) |
| 81 | except asyncio.TimeoutError: |
| 82 | log.warning(f"Some tasks did not complete within {timeout}s timeout") |
| 83 | |
| 84 | # 清理资源 - 改进弱引用处理 |
| 85 | cleaned_resources = 0 |
| 86 | failed_resources = 0 |
| 87 | for resource_ref in list(self._resources): |
| 88 | resource = resource_ref() |
| 89 | if resource is not None: |
| 90 | try: |
| 91 | if hasattr(resource, "close"): |
| 92 | if asyncio.iscoroutinefunction(resource.close): |
| 93 | await resource.close() |
| 94 | else: |
| 95 | resource.close() |
| 96 | elif hasattr(resource, "aclose"): |
| 97 | await resource.aclose() |
| 98 | cleaned_resources += 1 |
| 99 | except Exception as e: |
| 100 | log.warning(f"Failed to close resource {type(resource).__name__}: {e}") |
| 101 | failed_resources += 1 |
| 102 | # 如果弱引用已失效,资源已经被自动回收,无需操作 |
| 103 | |
| 104 | if cleaned_resources > 0: |
| 105 | log.info(f"Cleaned up {cleaned_resources} resources") |
| 106 | if failed_resources > 0: |
| 107 | log.warning(f"Failed to clean {failed_resources} resources") |
| 108 | |
| 109 | self._tasks.clear() |
| 110 | self._resources.clear() |
| 111 | log.info("TaskManager shutdown completed") |
| 112 | |
| 113 | @property |
| 114 | def is_shutdown(self) -> bool: |
no test coverage detected