Class: Core::Thresholder
Overview
Thresholder is an object that keeps track of how many calls are made to it and uses the volume over time to determine whether or not to run the associated block.
– get or create a thresholder named ‘foo’ thresholder = Core::Thresholder.instance(‘foo’, count: 60, seconds: 60)
– run block only if threshold is exceeded thresholder.exceeded { |count| puts “i have been called #count times” }
– run block only if threshold has not been exceeded thresholder.limit { |count| puts “i have been called #count times” }
– always run block and include current count thresholder.run { |count| puts “i have been called #count times” }
– reset counter thresholder.reset
Class Method Summary collapse
-
.forget(*names) ⇒ Object
forget a previously created thresholder.
-
.instance(*names, **args) ⇒ Object
return existing thresholder if it exists, otherwise create one.
Instance Method Summary collapse
-
#exceeded {|count| ... } ⇒ Object
run block if threshold is exceeded.
-
#limit {|count| ... } ⇒ Object
run block if threshold is not exceeded.
-
#reset ⇒ Object
reset internal counters.
-
#run {|update_and_return_count| ... } ⇒ Object
always run block.
Class Method Details
.forget(*names) ⇒ Object
forget a previously created thresholder
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/svcbase/thresholder.rb', line 42 def self.forget(*names) raise ArgumentError, 'no identifiers for threshold instance call' if names.empty? return unless @instances.dig(*names) @class_mutex.synchronize do if names.length == 1 @instances.delete names.last else @instances.dig(*names[0..-2])&.delete(names.last) end end end |
.instance(*names, **args) ⇒ Object
return existing thresholder if it exists, otherwise create one
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/svcbase/thresholder.rb', line 28 def self.instance(*names, **args) raise ArgumentError, 'no identifiers for threshold instance call' if names.empty? obj = @instances.dig(*names, :_instance) return obj if obj # create the appropriate instance @class_mutex.synchronize do obj = names.inject(@instances) { |buf, key| buf[key] ||= {} } obj[:_instance] ||= new(*names, **args) end end |
Instance Method Details
#exceeded {|count| ... } ⇒ Object
run block if threshold is exceeded
63 64 65 66 67 |
# File 'lib/svcbase/thresholder.rb', line 63 def exceeded raise 'No block passed to Thresholder#exceeded' unless block_given? count = update_and_return_count yield(count) if count > @max_count end |
#limit {|count| ... } ⇒ Object
run block if threshold is not exceeded
56 57 58 59 60 |
# File 'lib/svcbase/thresholder.rb', line 56 def limit raise 'No block passed to Thresholder#limit' unless block_given? count = update_and_return_count yield(count) if count <= @max_count end |
#reset ⇒ Object
reset internal counters
76 77 78 79 80 81 |
# File 'lib/svcbase/thresholder.rb', line 76 def reset @instance_mutex.synchronize do @queue = [] # each entry is a tuple [ <time>, <count> ] @count = 0 # current total count end end |
#run {|update_and_return_count| ... } ⇒ Object
always run block
70 71 72 73 |
# File 'lib/svcbase/thresholder.rb', line 70 def run raise 'No block passed to Thresholder#run' unless block_given? yield(update_and_return_count) end |