NOTE: This library is no longer under active development. Pull requests are, however, still being accepted.
Shopify maintains a gem with similar functionality called ruby-limiter.
glutton_ratelimit¶ ↑
A Ruby library for limiting the number of times a method can be invoked within a specified time period.
The rate-limiting is simple if somewhat naïve. Throttled methods are blocked using sleep.
The 1.x.x version of the library is designed to work with Ruby 2.4+. This is because the library was upgraded to use the Integer
class instead of Fixnum
.
Please use version 0.2.0 if you need to support an ealier version of Ruby.
Use Cases¶ ↑
You might wish to use this library to throttle code that:
-
Accesses a 3rd-party API that imposes a maximum rate-limit.
-
Scrapes data from any website where rapid repeated access is banned.
For example, EchoNest API requests need to be limited to 120 every minute.
Installation¶ ↑
gem install glutton_ratelimit
Or add the gem to your project Gemfile:
gem 'glutton_ratelimit'
If you need to use this gem with Ruby version 2.3 or ealier, use version 0.2.0 of the gem.
Types of Limiting¶ ↑
There are two types of rate limiting provided by this library:
-
Average Throttle Limiting (GluttonRatelimit::AveragedThrottle) DEFAULT
-
Bursty Token Bucket Limiting (GluttonRatelimit::BurstyTokenBucket)
Average Throttle (Default Mode)¶ ↑
If executions are limited to n times per m seconds then:
-
The first execution will occur immediately.
-
Before each of the remaining n-1 executions the process will attempt to sleep so that the executions are evenly spaced within the m second time period.
-
The process is repeated.
The amount of time slept before each execution will depend on the time period m and the average elapsed time of each execution.
Bursty Token Bucket¶ ↑
If executions are limited to n times per m seconds then:
-
n executions will be allowed immediately.
-
Before the next execution the process will sleep for the remainder of the m second time period.
-
The process is repeated.
The amount of time slept in step 2 will depend on how long the n executions took in step 1.
Instance Method Limiting Example¶ ↑
The rate_limit method can be used at the end of a class definition to limit specific instance methods.
rate_limit :name_of_instance_method, number_of_executions, timeframe_in_seconds
The specified instance method will be throlled to maintain an execution rate of:
timeframe_in_seconds / number_of_executions
An example where the limit_me instance method of the RateLimitTest class is throttled:¶ ↑
class RateLimitTest # The class must be extended to permit limiting. extend GluttonRatelimit def initialize @start = Time.now end def limit_me puts "#{Time.now - @start}" end # Throttle the limit_me method to five executions every sixty seconds. rate_limit :limit_me, 5, 60 end t = RateLimitTest.new 10.times { t.limit_me }
When using the rate_limit method the limiting defaults to GluttonRatelimit::AveragedThrottle. Token Bucket limiting can also be specified:
rate_limite :limit_me, 5, 60, GluttonRatelimit::BurstyTokenBucket
Simple Manual Limiting Example¶ ↑
Chunks of code can also be manually throttled using the times method of a specific GluttonRatelimit object.
# Maximum of twelve executions every five seconds. rl = GluttonRatelimit::BurstyTokenBucket.new 12, 5 # BurstyTokenBucket will allow for a full burst of executions followed by a pause. rl.times(25) do # Simulating a constant-time task: sleep 0.1 end # Maximum of six executions every six seconds. rl = GluttonRatelimit::AveragedThrottle.new 6, 6 # AverageThrottle will attempt to evenly space executions within the allowed period. rl.times(13) do # Simulating a 0 to 1 second random-time task: sleep rand end
More Examples¶ ↑
More examples can be found within the examples folder.
Warnings¶ ↑
Before using the library you should be aware of the following warnings.
Short Tasks and AveragedThrottle¶ ↑
The inaccuracy of Ruby’s sleep method may cause timing issues with the AveragedThrottle limiting. Specifically, the limiting accuracy may be slightly-off when trying to rate-limit quick methods (sub-millisecond tasks).
See: codeidol.com/other/rubyckbk/Date-and-Time/Waiting-a-Certain-Amount-of-Time
It is recommend that you use the BurstyTokenBucket limiting when throttling very short tasks.
Naive Throttling¶ ↑
As mentioned above, throttling is accomplish by blocking script execution using sleep. There is no support for dropping or queuing throttled method invocations.
This library is not thread safe.
Tests¶ ↑
The tests integration/timing tests with a tolerance of 0.5 of a percent outside the expected timings.
The tests can be run using:
bundle exec rake test
Thanks¶ ↑
Some of the algorithms were inspired by these discussions:
-
stackoverflow.com/questions/667508/whats-a-good-rate-limiting-algorithm
-
stackoverflow.com/questions/1407113/throttling-method-calls-to-m-requests-in-n-seconds
License¶ ↑
This is free and unencumbered software released into the public domain. See LICENSE for details.