-
-
Notifications
You must be signed in to change notification settings - Fork 2k
fix(aiocqhttp): enhance shutdown process for aiocqhttp adapter #5412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,5 @@ | ||||||||||||
| import asyncio | ||||||||||||
| import inspect | ||||||||||||
| import itertools | ||||||||||||
| import logging | ||||||||||||
| import time | ||||||||||||
|
|
@@ -436,7 +437,42 @@ def run(self) -> Awaitable[Any]: | |||||||||||
| return coro | ||||||||||||
|
|
||||||||||||
| async def terminate(self) -> None: | ||||||||||||
| self.shutdown_event.set() | ||||||||||||
| if hasattr(self, "shutdown_event"): | ||||||||||||
| self.shutdown_event.set() | ||||||||||||
| await self._close_reverse_ws_connections() | ||||||||||||
|
|
||||||||||||
| async def _close_reverse_ws_connections(self) -> None: | ||||||||||||
| api_clients = getattr(self.bot, "_wsr_api_clients", None) | ||||||||||||
| event_clients = getattr(self.bot, "_wsr_event_clients", None) | ||||||||||||
|
|
||||||||||||
| ws_clients: set[Any] = set() | ||||||||||||
| if isinstance(api_clients, dict): | ||||||||||||
| ws_clients.update(api_clients.values()) | ||||||||||||
| if isinstance(event_clients, set): | ||||||||||||
| ws_clients.update(event_clients) | ||||||||||||
|
|
||||||||||||
| close_tasks: list[Awaitable[Any]] = [] | ||||||||||||
| for ws in ws_clients: | ||||||||||||
| close_func = getattr(ws, "close", None) | ||||||||||||
| if not callable(close_func): | ||||||||||||
| continue | ||||||||||||
| try: | ||||||||||||
| close_result = close_func(code=1000, reason="Adapter shutdown") | ||||||||||||
| except TypeError: | ||||||||||||
| close_result = close_func() | ||||||||||||
| except Exception: | ||||||||||||
| continue | ||||||||||||
|
Comment on lines
+463
to
+464
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||
|
|
||||||||||||
| if inspect.isawaitable(close_result): | ||||||||||||
| close_tasks.append(close_result) | ||||||||||||
|
|
||||||||||||
| if close_tasks: | ||||||||||||
| await asyncio.gather(*close_tasks, return_exceptions=True) | ||||||||||||
|
|
||||||||||||
| if isinstance(api_clients, dict): | ||||||||||||
| api_clients.clear() | ||||||||||||
| if isinstance(event_clients, set): | ||||||||||||
| event_clients.clear() | ||||||||||||
|
|
||||||||||||
| async def shutdown_trigger_placeholder(self) -> None: | ||||||||||||
| await self.shutdown_event.wait() | ||||||||||||
|
|
||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): 在
close()过程中捕获并静默忽略所有异常,可能会掩盖真实的关闭问题。通过
except Exception: continue吞掉所有错误,会隐藏客户端close实现中的失败,从而让关闭相关问题难以排查。请至少在继续前把异常记录到日志中(例如 debug 级别),这样在不打断关闭流程的前提下,失败的关闭操作仍然是可观测的。建议实现:
为了让上述代码能正确编译并按预期工作,请确保:
在该模块中定义了一个 logger,例如在
aiocqhttp_platform_adapter.py顶部附近:import logginglogger = logging.getLogger(__name__)如果该模块已经在使用不同的日志记录约定(例如
self.logger或共享 logger),请将logger.debug(...)替换为与现有风格一致的日志记录引用。Original comment in English
suggestion (bug_risk): Catching and silently ignoring all exceptions during
close()may hide real shutdown issues.Swallowing all errors via
except Exception: continuehides failures in the client’scloseimplementation and makes shutdown issues hard to diagnose. Please at least log the exception (e.g. at debug level) before continuing so failed closes remain observable without interrupting shutdown.Suggested implementation:
To make this compile and work as intended, ensure that:
A logger is defined in this module, e.g. near the top of
aiocqhttp_platform_adapter.py:import logginglogger = logging.getLogger(__name__)If the module already uses a different logging convention (for example,
self.loggeror a shared logger), replacelogger.debug(...)with the appropriate logger reference to match the existing style.