Skip to content

Commit

Permalink
Add guild_ready_timeout to control the timeout of GUILD_CREATE stream
Browse files Browse the repository at this point in the history
This also fixes a timing issue where READY would take far too long to
load for big bot authors.

Closes Rapptz#4112
  • Loading branch information
Rapptz committed Jul 25, 2020
1 parent 1a9c5f4 commit bf02831
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 4 deletions.
5 changes: 5 additions & 0 deletions discord/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ class Client:
WebSocket in the case of not receiving a HEARTBEAT_ACK. Useful if
processing the initial packets take too long to the point of disconnecting
you. The default timeout is 60 seconds.
guild_ready_timeout: :class:`float`
The maximum number of seconds to wait for the GUILD_CREATE stream to end before
preparing the member cache and firing READY. The default timeout is 2 seconds.
.. versionadded:: 1.4
guild_subscriptions: :class:`bool`
Whether to dispatching of presence or typing events. Defaults to ``True``.
Expand Down
12 changes: 8 additions & 4 deletions discord/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ def __init__(self, *, dispatch, handlers, hooks, syncer, http, loop, **options):
self._ready_task = None
self._fetch_offline = options.get('fetch_offline_members', True)
self.heartbeat_timeout = options.get('heartbeat_timeout', 60.0)
self.guild_ready_timeout = options.get('guild_ready_timeout', 2.0)
if self.guild_ready_timeout < 0:
raise ValueError('guild_ready_timeout cannot be negative')

self.guild_subscriptions = options.get('guild_subscriptions', True)
allowed_mentions = options.get('allowed_mentions')

Expand Down Expand Up @@ -369,10 +373,10 @@ async def _delay_ready(self):
# only real bots wait for GUILD_CREATE streaming
if self.is_bot:
while True:
# this snippet of code is basically waiting 2 seconds
# this snippet of code is basically waiting N seconds
# until the last GUILD_CREATE was sent
try:
await asyncio.wait_for(launch.wait(), timeout=2.0)
await asyncio.wait_for(launch.wait(), timeout=self.guild_ready_timeout)
except asyncio.TimeoutError:
break
else:
Expand Down Expand Up @@ -1086,10 +1090,10 @@ async def _delay_ready(self):
await self.shards_launched.wait()
launch = self._ready_state.launch
while True:
# this snippet of code is basically waiting 2 * shard_ids seconds
# this snippet of code is basically waiting N seconds
# until the last GUILD_CREATE was sent
try:
await asyncio.wait_for(launch.wait(), timeout=2.0 * len(self.shard_ids))
await asyncio.wait_for(launch.wait(), timeout=self.guild_ready_timeout)
except asyncio.TimeoutError:
break
else:
Expand Down

0 comments on commit bf02831

Please sign in to comment.