Class SequentialRestRateLimiter

java.lang.Object
net.dv8tion.jda.api.requests.SequentialRestRateLimiter
All Implemented Interfaces:
RestRateLimiter

public final class SequentialRestRateLimiter extends Object implements RestRateLimiter
A bucket is determined via the Path+Method+Major in the following way:
  1. Get Hash from Path+Method (we call this route)
  2. Get bucket from Hash+Major (we call this bucketid)

If no hash is known we default to the constant "uninit" hash. The hash is loaded from HTTP responses using the "X-RateLimit-Bucket" response header. This hash is per Method+Path and can be stored indefinitely once received. Some endpoints don't return a hash, this means that the endpoint is uninit and will be in queue with only the major parameter.

To explain this further, lets look at the example of message history. The endpoint to fetch message history is GET/channels/{channel.id}/messages. This endpoint does not have any rate limit (uninit) and will thus use the hash uninit+GET/channels/{channel.id}/messages. The bucket id for this will be uninit+GET/channels/{channel.id}/messages:channel_id={channel.id} where {channel.id} would be replaced with the respective id. This means you can fetch history concurrently for multiple channels, but it will be in sequence for the same channel.

If the endpoint is not uninit we will receive a hash on the first response. Once this happens every uninit bucket will start moving its queue to the correct bucket. This is done during the queue work iteration so many requests to one endpoint would be moved correctly.

For example, the first message sending:


 public void onReady(ReadyEvent event) {
   TextChannel channel = event.getJDA().getTextChannelById("123");
   for (int i = 1; i <= 100; i++) {
     channel.sendMessage("Message: " + i).queue();
   }
 }
 

This will send 100 messages on startup. At this point we don't yet know the hash for this route, so we put them all in uninit+POST/channels/{channel.id}/messages:channel_id=123. The bucket iterates the requests in sync and gets the first response. This response provides the hash for this route, and we create a bucket for it. Once the response is handled we continue with the next request in the uninit bucket and notice the new bucket. We then move all related requests to this bucket.