fix(gateway): honor Discord connect timeout for ready wait
This commit is contained in:
parent
e675a60846
commit
46ab06c238
2 changed files with 57 additions and 3 deletions
|
|
@ -125,7 +125,7 @@ from tools.url_safety import is_safe_url
|
|||
async def _wait_for_ready_or_bot_exit(
|
||||
ready_event: asyncio.Event,
|
||||
bot_task: asyncio.Task,
|
||||
timeout: float,
|
||||
timeout: Optional[float],
|
||||
) -> None:
|
||||
"""Wait until Discord is ready, or surface early bot startup failure.
|
||||
|
||||
|
|
@ -328,6 +328,20 @@ def _build_allowed_mentions():
|
|||
)
|
||||
|
||||
|
||||
def _discord_ready_timeout_seconds() -> float:
|
||||
"""Return the Discord ready wait timeout during gateway startup."""
|
||||
raw = os.getenv("HERMES_GATEWAY_PLATFORM_CONNECT_TIMEOUT", "").strip()
|
||||
if raw:
|
||||
try:
|
||||
return max(0.0, float(raw))
|
||||
except ValueError:
|
||||
logger.warning(
|
||||
"Ignoring invalid HERMES_GATEWAY_PLATFORM_CONNECT_TIMEOUT=%r",
|
||||
raw,
|
||||
)
|
||||
return 30.0
|
||||
|
||||
|
||||
class VoiceReceiver:
|
||||
"""Captures and decodes voice audio from a Discord voice channel.
|
||||
|
||||
|
|
@ -1152,9 +1166,14 @@ class DiscordAdapter(BasePlatformAdapter):
|
|||
self._bot_task = asyncio.create_task(self._client.start(self.config.token))
|
||||
self._bot_task.add_done_callback(self._handle_bot_task_done)
|
||||
|
||||
ready_timeout = _discord_ready_timeout_seconds()
|
||||
# Wait for ready, but fail fast if discord.py's background startup
|
||||
# task dies first (for example on SOCKS/proxy connect errors).
|
||||
await _wait_for_ready_or_bot_exit(self._ready_event, self._bot_task, timeout=30)
|
||||
await _wait_for_ready_or_bot_exit(
|
||||
self._ready_event,
|
||||
self._bot_task,
|
||||
timeout=None if ready_timeout <= 0 else ready_timeout,
|
||||
)
|
||||
|
||||
self._running = True
|
||||
self._start_liveness_probe()
|
||||
|
|
|
|||
|
|
@ -382,7 +382,6 @@ async def test_connect_timeout_cancels_bot_task(monkeypatch):
|
|||
"leaving it alive creates a zombie Discord client that produces duplicate threads"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_disconnect_cancels_running_bot_task(monkeypatch):
|
||||
"""Regression: disconnect() must cancel _bot_task even when connect() timed out.
|
||||
|
|
@ -415,6 +414,42 @@ async def test_disconnect_cancels_running_bot_task(monkeypatch):
|
|||
assert zombie_task.cancelled(), "disconnect() must cancel the zombie bot task"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_connect_ready_wait_uses_gateway_platform_connect_timeout(monkeypatch):
|
||||
adapter = DiscordAdapter(PlatformConfig(enabled=True, token="test-token"))
|
||||
|
||||
monkeypatch.setenv("HERMES_GATEWAY_PLATFORM_CONNECT_TIMEOUT", "90")
|
||||
monkeypatch.setattr("gateway.status.acquire_scoped_lock", lambda scope, identity, metadata=None: (True, None))
|
||||
monkeypatch.setattr("gateway.status.release_scoped_lock", lambda scope, identity: None)
|
||||
|
||||
intents = SimpleNamespace(message_content=False, dm_messages=False, guild_messages=False, members=False, voice_states=False)
|
||||
monkeypatch.setattr(discord_platform.Intents, "default", lambda: intents)
|
||||
monkeypatch.setattr(
|
||||
discord_platform.commands,
|
||||
"Bot",
|
||||
lambda **kwargs: FakeBot(
|
||||
intents=kwargs["intents"],
|
||||
proxy=kwargs.get("proxy"),
|
||||
allowed_mentions=kwargs.get("allowed_mentions"),
|
||||
),
|
||||
)
|
||||
|
||||
seen_timeouts = []
|
||||
|
||||
async def fake_wait_for_ready(ready_event, bot_task, timeout):
|
||||
seen_timeouts.append(timeout)
|
||||
raise asyncio.TimeoutError()
|
||||
|
||||
monkeypatch.setattr(
|
||||
discord_platform, "_wait_for_ready_or_bot_exit", fake_wait_for_ready
|
||||
)
|
||||
|
||||
ok = await adapter.connect()
|
||||
|
||||
assert ok is False
|
||||
assert seen_timeouts == [90.0]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_connect_does_not_wait_for_slash_sync(monkeypatch):
|
||||
adapter = DiscordAdapter(PlatformConfig(enabled=True, token="test-token"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue