Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions gateway/platforms/discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,8 @@ async def on_voice_state_update(member, before, after):

async def disconnect(self) -> None:
"""Disconnect from Discord."""
await self._cancel_typing_tasks(reason="disconnect")

# Clean up all active voice connections before closing the client
for guild_id in list(self._voice_clients.keys()):
try:
Expand Down Expand Up @@ -899,6 +901,43 @@ async def disconnect(self) -> None:

logger.info("[%s] Disconnected", self.name)

async def cancel_background_tasks(self) -> None:
"""Cancel Discord-specific background loops plus base tasks."""
await self._cancel_typing_tasks(reason="shutdown")
await super().cancel_background_tasks()

async def _cancel_typing_tasks(self, reason: str = "cleanup") -> None:
"""Cancel all persistent typing loops owned by this adapter.

Discord keeps typing indicators alive with per-channel background tasks.
Those tasks are not part of BasePlatformAdapter's message-processing
task registry, so shutdown/restart must drain them explicitly.
"""
tasks = [(chat_id, task) for chat_id, task in self._typing_tasks.items()]
if not tasks:
return

self._typing_tasks.clear()
live_tasks = [task for _, task in tasks if not task.done()]
for task in live_tasks:
task.cancel()

if live_tasks:
try:
await asyncio.wait_for(
asyncio.gather(*live_tasks, return_exceptions=True),
timeout=2.0,
)
except asyncio.TimeoutError:
logger.warning(
"[%s] %d Discord typing task(s) did not exit within 2s during %s",
self.name,
len([task for task in live_tasks if not task.done()]),
reason,
)

logger.debug("[%s] Cleared %d Discord typing task(s) during %s", self.name, len(tasks), reason)

def _command_sync_state_path(self) -> _Path:
from hermes_constants import get_hermes_home

Expand Down
Loading