Class: Smartbill::Sdk::Transport::RateLimiter

Inherits:
Object
  • Object
show all
Defined in:
lib/smartbill/sdk/transport/rate_limiter.rb

Overview

Simple token-bucket limiter: max_calls per window_seconds.

Optionally enabled by clients to preempt the server’s 403.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_calls: 30, window_seconds: 10.0) ⇒ RateLimiter

Returns a new instance of RateLimiter.



12
13
14
15
16
17
# File 'lib/smartbill/sdk/transport/rate_limiter.rb', line 12

def initialize(max_calls: 30, window_seconds: 10.0)
  @max_calls = max_calls
  @window_seconds = window_seconds
  @timestamps = []
  @blocked_until = 0.0
end

Instance Attribute Details

#max_callsObject (readonly)

Returns the value of attribute max_calls.



10
11
12
# File 'lib/smartbill/sdk/transport/rate_limiter.rb', line 10

def max_calls
  @max_calls
end

#window_secondsObject (readonly)

Returns the value of attribute window_seconds.



10
11
12
# File 'lib/smartbill/sdk/transport/rate_limiter.rb', line 10

def window_seconds
  @window_seconds
end

Instance Method Details

#acquireObject

Raise RateLimitError if calling now would exceed the limit.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/smartbill/sdk/transport/rate_limiter.rb', line 20

def acquire
  now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  if now < @blocked_until
    wait = @blocked_until - now
    raise RateLimitError, format("Client-side rate limit: would block for %.1fs.", wait)
  end
  prune(now)
  if @timestamps.size >= @max_calls
    @blocked_until = @timestamps.first + @window_seconds
    wait = @blocked_until - now
    raise RateLimitError, format("Client-side rate limit exceeded: would block for %.1fs.", wait)
  end
  @timestamps << now
end

#notify_403Object

Record a server-side 403 so the limiter backs off for 10 minutes.



36
37
38
# File 'lib/smartbill/sdk/transport/rate_limiter.rb', line 36

def notify_403
  @blocked_until = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 600.0
end