fix(discord): slash registration and /skill refresh scan the catalog off the event loop
connect() called _register_slash_commands inline on every (re)connect, and /reload-skills called refresh_skill_group inline; both run discord_skill_commands_by_category, the same per-skill path-resolution walk the Telegram menu paid in #110707. On a 1.5k-skill install that holds the loop past the liveness watchdog. Registration now hops through asyncio.to_thread from connect(); refresh_skill_group is a coroutine that hops the rescan the same way (the reload handler already awaits an awaitable result). Contextvar-scoped profile overrides propagate through to_thread. One invariant test: the loop keeps ticking while the scan blocks, from both sites. Red on the PR head, green here. Review finding: Discord _register_slash_commands/refresh_skill_group ran the skill catalog disk scan synchronously on the event loop.
This commit is contained in:
@@ -1346,7 +1346,8 @@ class DiscordAdapter(DiscordMediaMixin, BasePlatformAdapter):
|
||||
guild_id,
|
||||
)
|
||||
if self._slash_commands:
|
||||
self._register_slash_commands()
|
||||
# Registration walks the skill catalog on disk (#110707); keep the loop free.
|
||||
await asyncio.to_thread(self._register_slash_commands)
|
||||
self._disconnecting = False
|
||||
self._bot_task = asyncio.create_task(self._client.start(self.config.token))
|
||||
self._bot_task.add_done_callback(self._handle_bot_task_done)
|
||||
@@ -4486,11 +4487,11 @@ class DiscordAdapter(DiscordMediaMixin, BasePlatformAdapter):
|
||||
self._skill_lookup = {n: (d, k) for n, d, k in entries}
|
||||
self._skill_group_hidden_count = hidden
|
||||
|
||||
def refresh_skill_group(self) -> tuple[int, int]:
|
||||
async def refresh_skill_group(self) -> tuple[int, int]:
|
||||
"""Rescan skills and refresh live ``/skill`` autocomplete; returns ``(new_count, hidden_count)``.
|
||||
Called after ``reload_skills``; no ``tree.sync()`` since autocomplete options are dynamic."""
|
||||
try:
|
||||
self._refresh_skill_catalog_state()
|
||||
await asyncio.to_thread(self._refresh_skill_catalog_state)
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"[%s] Failed to refresh /skill autocomplete after reload: %s", self.name, exc,
|
||||
|
||||
Reference in New Issue
Block a user