taycaldwell / riot-api-java

Riot Games API Java Library
http://taycaldwell.github.io/riot-api-java/
Apache License 2.0
192 stars 73 forks source link

RateLimit issue #121

Closed splitzyo closed 5 years ago

splitzyo commented 6 years ago

Hi, I ve been using this library to get different informations from League of Legends API and when I do, I get:

RateLimitException: Rate limit exceeded

What is the proper way to handle the rate limit and get 100 % of it ?

Linnun commented 6 years ago

The DefaultRateLimitHandler of this library only handles rate limits after it is too late. So basically if you already got a 429 response from the Riot Api, it will try to respect the Retry-After header for the given service, method or app.

There is also a BufferedRateLimitHandler in the current version of this library that, when configured properly, will try to prevent 429 responses by stopping to fire new requests early. Basically what it does is after a request it reads the rate limit headers from the Riot Api's response, and if the current usage is above X%, it will issue a manual X second cooldown on making requests to the given endpoint(s).

In a later version we also want to provide an AtomicRateLimitHandler (currently WIP) that tries to properly keep track of your rate limits by counting the requests you make and stopping a request when it would exceed the rate limit.

You can also write your own rate limiting logic by implementing the RateLimitHandler interface or extending the DefaultRateLimitHandler class. To use a non-default RateLimitHandler, use the #setRateLimitHandler() method of your ApiConfig.

For my personal use I created a custom RedisRateLimitHandler that basically uses a dedicated redis server to atomically manage rate limits for multiple dedicated servers using the same api key. This library is designed to give you a lot of freedom to create a RateLimitHandler that suits your specific use case best.

In any case, regardless of if the Riot Api throws a 'real' RateLimitException or if the RateLimitHandler of your choice prevents making a call (in which case it will throw a RespectedRateLimitException, which inherits RateLimitException), your request will fail and you will not get a response from it. What you can do is catch RateLimitException when you do a request. On that RateLimitException object you can call #getRetryAfter() which will give you an integer that is the amount of seconds you need to wait before you can fire the request again. It depends on the specific application if your best choice would be to sleep and retry the request, or drop it entirely.