Class: Lich::Common::Throttle

Inherits:
Object
  • Object
show all
Defined in:
documented/common/throttle.rb

Overview

Minimal monotonic-clock rate limiter: runs a block at most once per interval seconds and skips calls that arrive inside the window.

Extracted so the buffers' "sweep dead-thread entries, but not too often" logic lives in one place instead of being hand-rolled per call site.

Examples:

throttle = Lich::Common::Throttle.new(60.0)
throttle.run { expensive_cleanup } # runs now, and again >=60s later

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(interval) ⇒ Throttle

Returns a new instance of Throttle.

Parameters:

  • interval (Numeric)

    minimum seconds between runs



33
34
35
36
# File 'documented/common/throttle.rb', line 33

def initialize(interval)
  @interval    = interval.to_f
  @last_run_at = 0.0
end

Instance Attribute Details

#intervalFloat (readonly)

Returns minimum seconds between runs.

Returns:

  • (Float)

    minimum seconds between runs



25
26
27
# File 'documented/common/throttle.rb', line 25

def interval
  @interval
end

#last_run_atFloat

Monotonic timestamp of the last run. Exposed so callers (and tests) can open the gate (+0.0+) or close it (a recent timestamp) deterministically.

Returns:

  • (Float)


30
31
32
# File 'documented/common/throttle.rb', line 30

def last_run_at
  @last_run_at
end

Instance Method Details

#run { ... } ⇒ Boolean

Yields (running the guarded work) only when at least interval seconds have elapsed since the last run; the timestamp is stamped first so a run that raises still counts as an attempt.

A non-positive last_run_at (the initial/forced-open state) always runs, so the gate does not depend on the absolute value of the monotonic clock. CLOCK_MONOTONIC counts from an arbitrary epoch (often boot), so on a freshly-booted host now can be smaller than interval; comparing it against 0.0 directly would wrongly keep the first call gated.

Yields:

  • the work to rate-limit

Returns:

  • (Boolean)

    whether the block ran



50
51
52
53
54
55
56
57
# File 'documented/common/throttle.rb', line 50

def run
  now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  return false if @last_run_at.positive? && (now - @last_run_at) < @interval

  @last_run_at = now
  yield
  true
end