Class: Ocpp::Rails::RateLimiter

Inherits:
Object
  • Object
show all
Defined in:
app/services/ocpp/rails/rate_limiter.rb

Overview

Fixed-window rate limiter keyed by station identifier. The limit is re-read from the block on every call so configuration changes apply immediately; a nil limit disables throttling.

State is in-process: in multi-server deployments each node applies the limit independently, so treat the configured value as per node.

Constant Summary collapse

PRUNE_THRESHOLD =
1_000

Instance Method Summary collapse

Constructor Details

#initialize(window: 60, &limit) ⇒ RateLimiter

Returns a new instance of RateLimiter.



12
13
14
15
16
17
# File 'app/services/ocpp/rails/rate_limiter.rb', line 12

def initialize(window: 60, &limit)
  @window = window
  @limit = limit
  @mutex = Mutex.new
  @windows = {}
end

Instance Method Details

#allow?(key, now: Process.clock_gettime(Process::CLOCK_MONOTONIC)) ⇒ Boolean

Returns true when the event for this key is within the limit.

Returns:

  • (Boolean)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'app/services/ocpp/rails/rate_limiter.rb', line 20

def allow?(key, now: Process.clock_gettime(Process::CLOCK_MONOTONIC))
  limit = @limit.call
  return true if limit.nil?

  @mutex.synchronize do
    prune(now) if @windows.size > PRUNE_THRESHOLD

    started_at, count = @windows[key]
    if started_at.nil? || now - started_at >= @window
      @windows[key] = [ now, 1 ]
      true
    elsif count < limit
      @windows[key][1] += 1
      true
    else
      false
    end
  end
end

#reset!Object



40
41
42
# File 'app/services/ocpp/rails/rate_limiter.rb', line 40

def reset!
  @mutex.synchronize { @windows.clear }
end