Class: Rapidity::Limiter
- Inherits:
-
Object
- Object
- Rapidity::Limiter
- Defined in:
- lib/rapidity/limiter.rb
Constant Summary collapse
- LUA_SCRIPT_CODE =
File.read(File.join(__dir__, 'limiter.lua'))
Instance Attribute Summary collapse
-
#interval ⇒ Object
readonly
Returns the value of attribute interval.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#namespace ⇒ Object
readonly
Returns the value of attribute namespace.
-
#pool ⇒ Object
readonly
Returns the value of attribute pool.
-
#threshold ⇒ Object
readonly
Returns the value of attribute threshold.
Instance Method Summary collapse
- #ensure_script_loaded ⇒ Object
- #force_ttl(ttl) ⇒ Object
-
#initialize(pool, name:, interval: 10, threshold: 10, namespace: 'rapidity') ⇒ Limiter
constructor
Convert message to given class.
- #key(path) ⇒ Object
-
#obtain(count = 5, with_time: false) ⇒ Object
Obtain values from counter.
-
#remains ⇒ Object
Get current counter.
Constructor Details
#initialize(pool, name:, interval: 10, threshold: 10, namespace: 'rapidity') ⇒ Limiter
Convert message to given class
17 18 19 20 21 22 23 24 |
# File 'lib/rapidity/limiter.rb', line 17 def initialize(pool, name:, interval: 10, threshold: 10, namespace: 'rapidity') @pool = pool @interval = interval @threshold = threshold @name = name @namespace = namespace end |
Instance Attribute Details
#interval ⇒ Object (readonly)
Returns the value of attribute interval.
7 8 9 |
# File 'lib/rapidity/limiter.rb', line 7 def interval @interval end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
7 8 9 |
# File 'lib/rapidity/limiter.rb', line 7 def name @name end |
#namespace ⇒ Object (readonly)
Returns the value of attribute namespace.
7 8 9 |
# File 'lib/rapidity/limiter.rb', line 7 def namespace @namespace end |
#pool ⇒ Object (readonly)
Returns the value of attribute pool.
7 8 9 |
# File 'lib/rapidity/limiter.rb', line 7 def pool @pool end |
#threshold ⇒ Object (readonly)
Returns the value of attribute threshold.
7 8 9 |
# File 'lib/rapidity/limiter.rb', line 7 def threshold @threshold end |
Instance Method Details
#ensure_script_loaded ⇒ Object
92 93 94 95 96 |
# File 'lib/rapidity/limiter.rb', line 92 def ensure_script_loaded @script = @pool.with do |conn| conn.script(:load, LUA_SCRIPT_CODE) end end |
#force_ttl(ttl) ⇒ Object
86 87 88 89 90 |
# File 'lib/rapidity/limiter.rb', line 86 def force_ttl(ttl) @pool.with do |conn| conn.expire(key('remains'), ttl) end end |
#key(path) ⇒ Object
26 27 28 |
# File 'lib/rapidity/limiter.rb', line 26 def key(path) "#{namespace}:#{name}_#{path}" end |
#obtain(count = 5, with_time: false) ⇒ Object
Obtain values from counter
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/rapidity/limiter.rb', line 46 def obtain(count = 5, with_time: false) count = count.abs result = begin @pool.with do |conn| conn.evalsha(@script, keys: [key('remains')], argv: [threshold, interval, count]) end rescue Redis::CommandError => e if e..include?('NOSCRIPT') # The Redis server has never seen this script before. Needs to run only once in the entire lifetime # of the Redis server, until the script changes - in which case it will be loaded under a different SHA ensure_script_loaded retry else raise e end end taken = result[0].to_i time = Time.at(*result[1].map(&:to_i), :millisecond) if taken == 0 ttl = @pool.with do |conn| conn.ttl(key('remains')) end # UNKNOWN BUG? reset if no ttl present. Many years ago once upon time we meet our key without TTL if ttl == -1 STDERR.puts "ERROR[#{Time.now}]: TTL for key #{key('remains').inspect} disappeared!" @pool.with {|c| c.expire(key('remains'), interval) } end end if with_time [taken, time] else taken end end |
#remains ⇒ Object
Get current counter
32 33 34 35 36 37 38 39 40 |
# File 'lib/rapidity/limiter.rb', line 32 def remains results = @pool.with do |conn| conn.multi do |pipeline| pipeline.set(key('remains'), threshold, ex: interval, nx: true) pipeline.get(key('remains')) end end results[1].to_i #=> pipeline.get(key('remains')) end |