Class: Philiprehberger::RateCounter::Counter
- Inherits:
-
Object
- Object
- Philiprehberger::RateCounter::Counter
- Defined in:
- lib/philiprehberger/rate_counter.rb
Overview
A sliding-window rate counter for measuring event throughput
Instance Method Summary collapse
-
#count ⇒ Integer
Get the current event count within the window.
-
#increment(n = 1) ⇒ self
Increment the counter.
-
#initialize(window: 60) ⇒ Counter
constructor
Create a new rate counter.
-
#peak_rate ⇒ Float
Get the highest rate per second observed since creation or last reset.
-
#rate ⇒ Float
Get the rate of events per second.
-
#rate_per(unit) ⇒ Float
Get the rate projected to a specific time unit.
-
#reset ⇒ void
Reset the counter.
-
#snapshot ⇒ Hash
Return a frozen snapshot of the counter state.
-
#time_since_last ⇒ Float?
Get the number of seconds since the most recent increment.
Constructor Details
#initialize(window: 60) ⇒ Counter
Create a new rate counter
27 28 29 30 31 32 33 34 |
# File 'lib/philiprehberger/rate_counter.rb', line 27 def initialize(window: 60) raise Error, 'Window must be positive' unless window.is_a?(Numeric) && window.positive? @window = window @buckets = [] @peak_rate = 0.0 @mutex = Mutex.new end |
Instance Method Details
#count ⇒ Integer
Get the current event count within the window
53 54 55 56 57 58 |
# File 'lib/philiprehberger/rate_counter.rb', line 53 def count @mutex.synchronize do prune count_internal end end |
#increment(n = 1) ⇒ self
Increment the counter
40 41 42 43 44 45 46 47 48 |
# File 'lib/philiprehberger/rate_counter.rb', line 40 def increment(n = 1) @mutex.synchronize do @buckets << [now, n] prune current_rate = rate_internal @peak_rate = current_rate if current_rate > @peak_rate end self end |
#peak_rate ⇒ Float
Get the highest rate per second observed since creation or last reset
73 74 75 |
# File 'lib/philiprehberger/rate_counter.rb', line 73 def peak_rate @mutex.synchronize { @peak_rate } end |
#rate ⇒ Float
Get the rate of events per second
63 64 65 66 67 68 |
# File 'lib/philiprehberger/rate_counter.rb', line 63 def rate @mutex.synchronize do prune rate_internal end end |
#rate_per(unit) ⇒ Float
Get the rate projected to a specific time unit
113 114 115 116 117 118 |
# File 'lib/philiprehberger/rate_counter.rb', line 113 def rate_per(unit) multiplier = RATE_UNITS[unit] raise Error, "Unknown unit: #{unit}. Use :second, :minute, or :hour" unless multiplier rate * multiplier end |
#reset ⇒ void
This method returns an undefined value.
Reset the counter
123 124 125 126 127 128 |
# File 'lib/philiprehberger/rate_counter.rb', line 123 def reset @mutex.synchronize do @buckets.clear @peak_rate = 0.0 end end |
#snapshot ⇒ Hash
Return a frozen snapshot of the counter state
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/philiprehberger/rate_counter.rb', line 80 def snapshot @mutex.synchronize do prune { count: count_internal, rate: rate_internal, peak_rate: @peak_rate, window: @window, timestamp: Process.clock_gettime(Process::CLOCK_MONOTONIC) }.freeze end end |
#time_since_last ⇒ Float?
Get the number of seconds since the most recent increment
Returns ‘nil` if the counter has never been incremented or if all events have fully expired from the sliding window.
99 100 101 102 103 104 105 106 |
# File 'lib/philiprehberger/rate_counter.rb', line 99 def time_since_last @mutex.synchronize do prune return nil if @buckets.empty? now - @buckets.last[0] end end |