Working with the Shopify API our application had to throttle the number of HTTP requests we make to the API. A brief background; our integration later would retrieve products from a 3rd party system, perform a diff to see what has changed and publish to a queue the products that need to be updated. Apache Camel route would listen to the queue and do the necessary updates on Shopify Products or Variants.

As the messages are read of the queue we would end up sending too many requests per second due to concurrent processing by Apache Camel. Its works, that how JMS is supposed to work.

From Shopify;

The API call limit operates using a “leaky bucket” algorithm as a controller. This allows for infrequent bursts of calls, and allows your app to continue to make an unlimited amount of calls over time. The bucket size is 40 calls (which cannot be exceeded at any given time), with a “leak rate” of 2 calls per second that continually empties the bucket. If your app averages 2 calls per second, it will never trip a 429 error (“bucket overflow”). To learn more about the algorithm in general, click here.

To fix this Shopify suggests limiting to 2 requests per seconds

Enter Google Guice!

Google Guice provides a RateLimiter class. From the javadocs;

A rate limiter. Conceptually, a rate limiter distributes permits at a configurable rate. Each acquire() blocks if necessary until a permit is available, and then takes it. Once acquired, permits need not be released.

Rate limiters are often used to restrict the rate at which some physical or logical resource is accessed. This is in contrast to java.util.concurrent.Semaphore which restricts the number of concurrent accesses instead of the rate (note though that concurrency and rate are closely related, e.g. see Little’s Law).

A RateLimiter is defined primarily by the rate at which permits are issued. Absent additional configuration, permits will be distributed at a fixed rate, defined in terms of permits per second. Permits will be distributed smoothly, with the delay between individual permits being adjusted to ensure that the configured rate is maintained.

creates a rate limiter that will make sure only 2 permits are issued per second. Other threads are blocked until they can acquire a permit.