Class: Fizzy::RateLimiter

Inherits:
Object
  • Object
show all
Defined in:
lib/fizzy/rate_limiter.rb

Overview

Token bucket rate limiter for client-side rate limiting.

Prevents the client from exceeding a configurable request rate, avoiding 429 responses from the server.

Examples:

limiter = Fizzy::RateLimiter.new(rate: 10, burst: 20)
limiter.acquire  # blocks until a token is available

Instance Method Summary collapse

Constructor Details

#initialize(rate: 10, burst: 20) ⇒ RateLimiter

Returns a new instance of RateLimiter.

Parameters:

  • rate (Numeric) (defaults to: 10)

    tokens per second (sustained rate)

  • burst (Integer) (defaults to: 20)

    maximum token bucket size (burst capacity)



15
16
17
18
19
20
21
# File 'lib/fizzy/rate_limiter.rb', line 15

def initialize(rate: 10, burst: 20)
  @rate = rate.to_f
  @burst = burst
  @tokens = burst.to_f
  @last_refill = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  @mutex = Mutex.new
end

Instance Method Details

#acquirevoid

This method returns an undefined value.

Acquires a token, blocking if necessary until one is available.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/fizzy/rate_limiter.rb', line 26

def acquire
  loop do
    wait_time = nil

    @mutex.synchronize do
      refill
      if @tokens >= 1.0
        @tokens -= 1.0
        return
      else
        wait_time = (1.0 - @tokens) / @rate
      end
    end

    sleep(wait_time) if wait_time&.positive?
  end
end

#try_acquireBoolean

Attempts to acquire a token without blocking.

Returns:

  • (Boolean)

    true if a token was acquired



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/fizzy/rate_limiter.rb', line 47

def try_acquire
  @mutex.synchronize do
    refill
    if @tokens >= 1.0
      @tokens -= 1.0
      true
    else
      false
    end
  end
end