Class: SimpleThrottle
- Inherits:
-
Object
- Object
- SimpleThrottle
- Defined in:
- lib/simple_throttle.rb
Overview
Create a simple throttle that can be used to limit the number of request for a resouce per time period. These objects are thread safe.
Constant Summary collapse
- @@lock =
Mutex.new
Instance Attribute Summary collapse
-
#limit ⇒ Object
readonly
Returns the value of attribute limit.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#ttl ⇒ Object
readonly
Returns the value of attribute ttl.
Class Method Summary collapse
-
.[](name) ⇒ Object
Returns a globally defined throttle with the specfied name.
-
.add(name, limit:, ttl:) ⇒ Object
Add a global throttle that can be referenced later with the [] method.
-
.redis ⇒ Object
Return the Redis instance where the throttles are stored.
-
.set_redis(client = nil, &block) ⇒ Object
Set the Redis instance to use for maintaining the throttle.
Instance Method Summary collapse
-
#allowed! ⇒ Object
Returns true if the limit for the throttle has not been reached yet.
-
#initialize(name, limit:, ttl:) ⇒ SimpleThrottle
constructor
Create a new throttle with the given name.
-
#peek ⇒ Object
Peek at the current number for throttled calls being tracked.
-
#reset! ⇒ Object
Reset a throttle back to zero.
-
#wait_time ⇒ Object
Returns when the next resource call should be allowed.
Constructor Details
#initialize(name, limit:, ttl:) ⇒ SimpleThrottle
Create a new throttle with the given name. The ttl argument specifies the time range that is being used for measuring in seconds while the limit specifies how many calls are allowed in that range.
52 53 54 55 56 57 58 |
# File 'lib/simple_throttle.rb', line 52 def initialize(name, limit:, ttl:) @name = name.to_s @name.freeze unless @name.frozen? @limit = limit @ttl = ttl @script_sha_1 = nil end |
Instance Attribute Details
#limit ⇒ Object (readonly)
Returns the value of attribute limit.
47 48 49 |
# File 'lib/simple_throttle.rb', line 47 def limit @limit end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
47 48 49 |
# File 'lib/simple_throttle.rb', line 47 def name @name end |
#ttl ⇒ Object (readonly)
Returns the value of attribute ttl.
47 48 49 |
# File 'lib/simple_throttle.rb', line 47 def ttl @ttl end |
Class Method Details
.[](name) ⇒ Object
Returns a globally defined throttle with the specfied name.
20 21 22 23 24 25 26 |
# File 'lib/simple_throttle.rb', line 20 def [](name) if defined?(@throttles) && @throttles @throttles[name.to_s] else nil end end |
.add(name, limit:, ttl:) ⇒ Object
Add a global throttle that can be referenced later with the [] method.
12 13 14 15 16 17 |
# File 'lib/simple_throttle.rb', line 12 def add(name, limit:, ttl:) @@lock.synchronize do @throttles ||= {} @throttles[name.to_s] = new(name, limit: limit, ttl: ttl) end end |
.redis ⇒ Object
Return the Redis instance where the throttles are stored.
38 39 40 41 42 43 44 |
# File 'lib/simple_throttle.rb', line 38 def redis if @redis_client.is_a?(Proc) @redis_client.call else @redis_client end end |
.set_redis(client = nil, &block) ⇒ Object
Set the Redis instance to use for maintaining the throttle. This can either be set with a hard coded value or by the value yielded by a block. If the block form is used it will be invoked at runtime to get the instance. Use this method if your Redis instance isn’t constant (for example if you’re in a forking environment and re-initialize connections on fork)
33 34 35 |
# File 'lib/simple_throttle.rb', line 33 def set_redis(client = nil, &block) @redis_client = (client || block) end |
Instance Method Details
#allowed! ⇒ Object
Returns true if the limit for the throttle has not been reached yet. This method will also track the throttled resource as having been invoked on each call.
62 63 64 65 66 67 68 69 |
# File 'lib/simple_throttle.rb', line 62 def allowed! size = current_size(true) if size < limit true else false end end |
#peek ⇒ Object
Peek at the current number for throttled calls being tracked.
77 78 79 |
# File 'lib/simple_throttle.rb', line 77 def peek current_size(false) end |
#reset! ⇒ Object
Reset a throttle back to zero.
72 73 74 |
# File 'lib/simple_throttle.rb', line 72 def reset! self.class.redis.del(redis_key) end |
#wait_time ⇒ Object
Returns when the next resource call should be allowed. Note that this doesn’t guarantee that calling allow! will return true if the wait time is zero since other processes or threads can claim the resource.
84 85 86 87 88 89 90 91 92 93 |
# File 'lib/simple_throttle.rb', line 84 def wait_time if peek < limit 0.0 else first = self.class.redis.lindex(redis_key, 0).to_f / 1000.0 delta = Time.now.to_f - first delta = 0.0 if delta < 0 delta end end |