class Rate
Tracks rate information over a sliding time window using a circular buffer.
Definitions
def initialize(window: 60)
Initialize the event rate counter.
Signature
-
parameter
windowInteger The time window in seconds for rate calculations.
Implementation
def initialize(window: 60)
@window = window
@samples = [0] * @window
@last_update = Array.new(@window, 0)
end
attr :window
The time window in seconds for rate calculations.
def now
Get the current time in seconds.
Signature
-
returns
Integer The current monotonic time in seconds.
Implementation
def now
::Process.clock_gettime(::Process::CLOCK_MONOTONIC).to_i
end
def add(value = 1, time: self.now)
Add a value to the current time slot.
Signature
-
parameter
valueNumeric The value to add (default: 1)
-
parameter
timeInteger The current time in seconds (default: monotonic time)
Implementation
def add(value = 1, time: self.now)
index = time % @samples.size
# If this slot hasn't been updated in a full window cycle, reset it
if (time - @last_update[index]) >= @window
@samples[index] = 0
end
@samples[index] += value
@last_update[index] = time
end
def total(time: self.now)
Get the total count in the current window.
Signature
-
parameter
timeInteger The current time in seconds (default: monotonic time)
-
returns
Numeric The sum of all samples in the window.
Implementation
def total(time: self.now)
@samples.each_with_index.sum do |value, index|
# Only count samples that are within the window (inclusive of window boundary)
if (time - @last_update[index]) <= @window
value
else
0
end
end
end
def per_second(time: self.now)
Get the rate per second over the window.
Signature
-
parameter
timeInteger The current time in seconds (default: monotonic time)
-
returns
Float The average rate per second.
Implementation
def per_second(time: self.now)
total(time: time).to_f / @window
end
def per_minute(time: self.now)
Get the rate per minute over the window.
Signature
-
parameter
timeInteger The current time in seconds (default: monotonic time)
-
returns
Float The average rate per minute.
Implementation
def per_minute(time: self.now)
per_second(time: time) * 60
end