chenwardT / lol_stats2

Website to perform match aggregation and analysis for Riot Games' League of Legends.
2 stars 0 forks source link

Employ Riot's API's response headers #9

Closed chenwardT closed 8 years ago

chenwardT commented 8 years ago

Riot recently implemented headers in their responses that indicate useful information regarding rate limits and errors related to them:

If a call exceeds the user or service rate limit for a given period of time, then subsequent calls made to limited endpoints will return a 429 "Rate limit exceeded" HTTP response until the rate limit expires.

In addition to the response code, some additional headers will be included in the response that provide more information.

Retry-After - The remaining number of seconds before the rate limit resets. X-Rate-Limit-Type - The rate limit type, either "user" or "service". If the above headers are not included in the response, then the rate limit was not enforced by the API infrastructure, but rather by the underlying service to which the request was proxied.

See https://developer.riotgames.com/docs/rate-limiting

We should use this to inform arguments to retry for tasks. See http://docs.celeryproject.org/en/latest/userguide/tasks.html#retrying

chenwardT commented 8 years ago

Example e.__dict__ in riot_api task after making too many requests:

{
   'headers':{
      'Content-Length':'66',
      'Content-Type':'application/json; charset=UTF-8',
      'X-Rate-Limit-Type':'user',
      'Server':'Jetty(9.1.5.v20140505)',
      'Retry-After':'9',
      'Connection':'keep-alive'
   },
   'error':'Too many requests'
}

Example response.__dict__ from riotwatcher.py: raise_status function after too many requests:

{
   '_content_consumed':True,
   'request':<PreparedRequest   [
      GET
   ]   >,
   'cookies':<RequestsCookieJar   [

   ]   >,
   'encoding':'UTF-8',
   'elapsed':datetime.timedelta(0,
   0,
   465555   ),
   'url':'https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/ronfar?api_key=<KEY HERE>',
   'connection':<requests.adapters.HTTPAdapter object at 0x7f5b655be550>,
   'status_code':429,
   'history':[

   ],
   'raw':<requests.packages.urllib3.response.HTTPResponse object at 0x7f5b655d5a58>,
   'headers':{
      'Connection':'keep-alive',
      'Content-Type':'application/json; charset=UTF-8',
      'Server':'Jetty(9.1.5.v20140505)',
      'X-Rate-Limit-Type':'user',
      'Content-Length':'66',
      'Retry-After':'5'
   },
   'reason':'429',
   '_content':b'   {
      "status":{
         "message":"Rate limit exceeded",
         "status_code":429
      }
   }
}
chenwardT commented 8 years ago

Using Retry-After header to inform retry delay now, see https://github.com/chenwardT/lol_stats2/commit/c60e7b89e99eda543cf05f7426a152a666c342cb

However, if a large enough number of tasks hit the limit around the same time, they'd each retry at the same delay, some would again exceed the rate limit, so this is of limited usefulness.