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 <noreply@anthropic.com>
This commit is contained in:
02356abc 2026-05-18 19:32:37 -07:00 committed by Teknium
parent e73e487d40
commit 8dca28775e

View file

@ -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: