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.
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 new 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.
47 48 49 50 51 52 53 |
# File 'lib/simple_throttle.rb', line 47 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.
42 43 44 |
# File 'lib/simple_throttle.rb', line 42 def limit @limit end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
42 43 44 |
# File 'lib/simple_throttle.rb', line 42 def name @name end |
#ttl ⇒ Object (readonly)
Returns the value of attribute ttl.
42 43 44 |
# File 'lib/simple_throttle.rb', line 42 def ttl @ttl end |
Class Method Details
.[](name) ⇒ Object
Returns a globally defined throttle with the specfied name.
15 16 17 18 19 20 21 |
# File 'lib/simple_throttle.rb', line 15 def [](name) if defined?(@throttles) && @throttles @throttles[name.to_s] else nil end end |
.add(name, limit:, ttl:) ⇒ Object
Add a new throttle that can be referenced later with the [] method.
9 10 11 12 |
# File 'lib/simple_throttle.rb', line 9 def add(name, limit:, ttl:) @throttles ||= {} @throttles[name.to_s] = new(name, limit: limit, ttl: ttl) end |
.redis ⇒ Object
Return the Redis instance where the throttles are stored.
33 34 35 36 37 38 39 |
# File 'lib/simple_throttle.rb', line 33 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)
28 29 30 |
# File 'lib/simple_throttle.rb', line 28 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.
57 58 59 60 61 62 63 64 |
# File 'lib/simple_throttle.rb', line 57 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.
72 73 74 |
# File 'lib/simple_throttle.rb', line 72 def peek current_size(false) end |
#reset! ⇒ Object
Reset a throttle back to zero.
67 68 69 |
# File 'lib/simple_throttle.rb', line 67 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.
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/simple_throttle.rb', line 79 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 |