diff options
| author | Rapptz <[email protected]> | 2018-06-10 18:09:14 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2018-06-10 18:10:00 -0400 |
| commit | f25091efe1281aebe70189c61f9cac405b21a72f (patch) | |
| tree | d0d13dad1a89de9f45845a36ea475098b7a0b494 /discord/shard.py | |
| parent | Add Message.jump_to_url (diff) | |
| download | discord.py-f25091efe1281aebe70189c61f9cac405b21a72f.tar.xz discord.py-f25091efe1281aebe70189c61f9cac405b21a72f.zip | |
Drop support for Python 3.4 and make minimum version 3.5.2.
Diffstat (limited to 'discord/shard.py')
| -rw-r--r-- | discord/shard.py | 91 |
1 files changed, 37 insertions, 54 deletions
diff --git a/discord/shard.py b/discord/shard.py index 284f5cdc..a7fec0c4 100644 --- a/discord/shard.py +++ b/discord/shard.py @@ -43,7 +43,7 @@ class Shard: self.ws = ws self._client = client self.loop = self._client.loop - self._current = compat.create_future(self.loop) + self._current = self.loop.create_future() self._current.set_result(None) # we just need an already done future self._pending = asyncio.Event(loop=self.loop) self._pending_task = None @@ -58,47 +58,36 @@ class Shard: def complete_pending_reads(self): self._pending.set() - def _pending_reads(self): + async def _pending_reads(self): try: while self.is_pending(): - yield from self.poll() + await self.poll() except asyncio.CancelledError: pass def launch_pending_reads(self): - self._pending_task = compat.create_task(self._pending_reads(), loop=self.loop) + self._pending_task = asyncio.ensure_future(self._pending_reads(), loop=self.loop) def wait(self): return self._pending_task - @asyncio.coroutine - def poll(self): + async def poll(self): try: - yield from self.ws.poll_event() + await self.ws.poll_event() except ResumeWebSocket as e: log.info('Got a request to RESUME the websocket at Shard ID %s.', self.id) coro = DiscordWebSocket.from_client(self._client, resume=True, shard_id=self.id, session=self.ws.session_id, sequence=self.ws.sequence) - self.ws = yield from asyncio.wait_for(coro, timeout=180.0, loop=self.loop) + self.ws = await asyncio.wait_for(coro, timeout=180.0, loop=self.loop) def get_future(self): if self._current.done(): - self._current = compat.create_task(self.poll(), loop=self.loop) + self._current = asyncio.ensure_future(self.poll(), loop=self.loop) return self._current -def _ensure_coroutine_connect(gateway, loop): - # In 3.5+ websockets.connect does not return a coroutine, but an awaitable. - # The problem is that in 3.5.0 and in some cases 3.5.1, asyncio.ensure_future and - # by proxy, asyncio.wait_for, do not accept awaitables, but rather futures or coroutines. - # By wrapping it up into this function we ensure that it's in a coroutine and not an awaitable - # even for 3.5.0 users. - ws = yield from websockets.connect(gateway, loop=loop, klass=DiscordWebSocket) - return ws - class AutoShardedClient(Client): """A client similar to :class:`Client` except it handles the complications of sharding for the user into a more manageable and transparent single @@ -149,8 +138,7 @@ class AutoShardedClient(Client): self._connection._get_websocket = _get_websocket - @asyncio.coroutine - def _chunker(self, guild, *, shard_id=None): + async def _chunker(self, guild, *, shard_id=None): try: guild_id = guild.id shard_id = shard_id or guild.shard_id @@ -167,7 +155,7 @@ class AutoShardedClient(Client): } ws = self.shards[shard_id].ws - yield from ws.send_as_json(payload) + await ws.send_as_json(payload) @property def latency(self): @@ -189,8 +177,7 @@ class AutoShardedClient(Client): """ return [(shard_id, shard.ws.latency) for shard_id, shard in self.shards.items()] - @asyncio.coroutine - def request_offline_members(self, *guilds): + async def request_offline_members(self, *guilds): """|coro| Requests previously offline members from the guild to be filled up @@ -219,16 +206,16 @@ class AutoShardedClient(Client): _guilds = sorted(guilds, key=lambda g: g.shard_id) for shard_id, sub_guilds in itertools.groupby(_guilds, key=lambda g: g.shard_id): sub_guilds = list(sub_guilds) - yield from self._connection.request_offline_members(sub_guilds, shard_id=shard_id) + await self._connection.request_offline_members(sub_guilds, shard_id=shard_id) - @asyncio.coroutine - def launch_shard(self, gateway, shard_id): + async def launch_shard(self, gateway, shard_id): try: - ws = yield from asyncio.wait_for(_ensure_coroutine_connect(gateway, self.loop), loop=self.loop, timeout=180.0) + coro = websockets.connect(gateway, loop=self.loop, klass=DiscordWebSocket) + ws = await asyncio.wait_for(coro, loop=self.loop, timeout=180.0) except Exception as e: log.info('Failed to connect for shard_id: %s. Retrying...', shard_id) - yield from asyncio.sleep(5.0, loop=self.loop) - return (yield from self.launch_shard(gateway, shard_id)) + await asyncio.sleep(5.0, loop=self.loop) + return (await self.launch_shard(gateway, shard_id)) ws.token = self.http.token ws._connection = self._connection @@ -240,31 +227,30 @@ class AutoShardedClient(Client): try: # OP HELLO - yield from asyncio.wait_for(ws.poll_event(), loop=self.loop, timeout=180.0) - yield from asyncio.wait_for(ws.identify(), loop=self.loop, timeout=180.0) + await asyncio.wait_for(ws.poll_event(), loop=self.loop, timeout=180.0) + await asyncio.wait_for(ws.identify(), loop=self.loop, timeout=180.0) except asyncio.TimeoutError: log.info('Timed out when connecting for shard_id: %s. Retrying...', shard_id) - yield from asyncio.sleep(5.0, loop=self.loop) - return (yield from self.launch_shard(gateway, shard_id)) + await asyncio.sleep(5.0, loop=self.loop) + return (await self.launch_shard(gateway, shard_id)) # keep reading the shard while others connect self.shards[shard_id] = ret = Shard(ws, self) ret.launch_pending_reads() - yield from asyncio.sleep(5.0, loop=self.loop) + await asyncio.sleep(5.0, loop=self.loop) - @asyncio.coroutine - def launch_shards(self): + async def launch_shards(self): if self.shard_count is None: - self.shard_count, gateway = yield from self.http.get_bot_gateway() + self.shard_count, gateway = await self.http.get_bot_gateway() else: - gateway = yield from self.http.get_gateway() + gateway = await self.http.get_gateway() self._connection.shard_count = self.shard_count shard_ids = self.shard_ids if self.shard_ids else range(self.shard_count) for shard_id in shard_ids: - yield from self.launch_shard(gateway, shard_id) + await self.launch_shard(gateway, shard_id) shards_to_wait_for = [] for shard in self.shards.values(): @@ -272,21 +258,19 @@ class AutoShardedClient(Client): shards_to_wait_for.append(shard.wait()) # wait for all pending tasks to finish - yield from utils.sane_wait_for(shards_to_wait_for, timeout=300.0, loop=self.loop) + await utils.sane_wait_for(shards_to_wait_for, timeout=300.0, loop=self.loop) - @asyncio.coroutine - def _connect(self): - yield from self.launch_shards() + async def _connect(self): + await self.launch_shards() while True: pollers = [shard.get_future() for shard in self.shards.values()] - done, pending = yield from asyncio.wait(pollers, loop=self.loop, return_when=asyncio.FIRST_COMPLETED) + done, pending = await asyncio.wait(pollers, loop=self.loop, return_when=asyncio.FIRST_COMPLETED) for f in done: # we wanna re-raise to the main Client.connect handler if applicable f.result() - @asyncio.coroutine - def close(self): + async def close(self): """|coro| Closes the connection to discord. @@ -298,16 +282,15 @@ class AutoShardedClient(Client): for vc in self.voice_clients: try: - yield from vc.disconnect() + await vc.disconnect() except: pass to_close = [shard.ws.close() for shard in self.shards.values()] - yield from asyncio.wait(to_close, loop=self.loop) - yield from self.http.close() + await asyncio.wait(to_close, loop=self.loop) + await self.http.close() - @asyncio.coroutine - def change_presence(self, *, activity=None, status=None, afk=False, shard_id=None): + async def change_presence(self, *, activity=None, status=None, afk=False, shard_id=None): """|coro| Changes the client's presence. @@ -355,12 +338,12 @@ class AutoShardedClient(Client): if shard_id is None: for shard in self.shards.values(): - yield from shard.ws.change_presence(activity=activity, status=status, afk=afk) + await shard.ws.change_presence(activity=activity, status=status, afk=afk) guilds = self._connection.guilds else: shard = self.shards[shard_id] - yield from shard.ws.change_presence(activity=activity, status=status, afk=afk) + await shard.ws.change_presence(activity=activity, status=status, afk=afk) guilds = [g for g in self._connection.guilds if g.shard_id == shard_id] for guild in guilds: |