From 8dca28775ef03841744563e7b5bc15839ae3d807 Mon Sep 17 00:00:00 2001 From: 02356abc <198679067+02356abc@users.noreply.github.com> Date: Mon, 18 May 2026 19:32:37 -0700 Subject: [PATCH] fix(wecom): handle WSMsgType.CLOSING to prevent CPU spin The WeCom adapter's _read_events() loop only handled CLOSE, CLOSED, and ERROR websocket message types. When the server initiates a graceful shutdown, aiohttp returns WSMsgType.CLOSING before the connection is fully closed. This message type was not handled, causing the receive() call to return immediately in a tight loop while self._ws.closed remained False. The result was 100% CPU usage on the asyncio event loop. Add WSMsgType.CLOSING to the set of terminal message types that raise RuntimeError("WeCom websocket closed"), allowing _listen_loop() to enter its normal reconnect backoff path. Co-Authored-By: Claude Sonnet 4.6 --- gateway/platforms/wecom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/platforms/wecom.py b/gateway/platforms/wecom.py index 96769ea59b1..5aad1e09cc5 100644 --- a/gateway/platforms/wecom.py +++ b/gateway/platforms/wecom.py @@ -361,7 +361,7 @@ class WeComAdapter(BasePlatformAdapter): payload = self._parse_json(msg.data) if payload: await self._dispatch_payload(payload) - elif msg.type in {aiohttp.WSMsgType.CLOSE, aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR}: + elif msg.type in {aiohttp.WSMsgType.CLOSE, aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR, aiohttp.WSMsgType.CLOSING}: raise RuntimeError("WeCom websocket closed") async def _heartbeat_loop(self) -> None: