Rewrite HTTP handling significantly.

This should have a more uniform approach to rate limit handling. Instead
of queueing every request, wait until we receive a 429 and then block
the requesting bucket until we're done being rate limited. This should
reduce the number of 429s done by the API significantly (about 66% avg).

This also consistently checks for 502 retries across all requests.
This commit is contained in:
Rapptz
2016-06-12 20:32:59 -04:00
parent fa36a449e9
commit 1fba1b06fa
3 changed files with 585 additions and 480 deletions

View File

@ -40,7 +40,7 @@ import struct
log = logging.getLogger(__name__)
__all__ = [ 'ReconnectWebSocket', 'get_gateway', 'DiscordWebSocket',
__all__ = [ 'ReconnectWebSocket', 'DiscordWebSocket',
'KeepAliveHandler', 'VoiceKeepAliveHandler',
'DiscordVoiceWebSocket', 'ResumeWebSocket' ]
@ -97,36 +97,6 @@ class VoiceKeepAliveHandler(KeepAliveHandler):
'd': int(time.time() * 1000)
}
@asyncio.coroutine
def get_gateway(token, *, loop=None):
"""Returns the gateway URL for connecting to the WebSocket.
Parameters
-----------
token : str
The discord authentication token.
loop
The event loop.
Raises
------
GatewayNotFound
When the gateway is not returned gracefully.
"""
headers = {
'authorization': token,
'content-type': 'application/json'
}
with aiohttp.ClientSession(loop=loop) as session:
resp = yield from session.get(endpoints.GATEWAY, headers=headers)
if resp.status != 200:
yield from resp.release()
raise GatewayNotFound()
data = yield from resp.json(encoding='utf-8')
return data.get('url') + '?encoding=json&v=4'
class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
"""Implements a WebSocket for Discord's gateway v4.
@ -190,11 +160,11 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
This is for internal use only.
"""
gateway = yield from get_gateway(client.token, loop=client.loop)
gateway = yield from client.http.get_gateway()
ws = yield from websockets.connect(gateway, loop=client.loop, klass=cls)
# dynamically add attributes needed
ws.token = client.token
ws.token = client.http.token
ws._connection = client.connection
ws._dispatch = client.dispatch
ws.gateway = gateway
@ -505,7 +475,7 @@ class DiscordVoiceWebSocket(websockets.client.WebSocketClientProtocol):
'server_id': client.guild_id,
'user_id': client.user.id,
'session_id': client.session_id,
'token': client.token
'token': client.http.token
}
}