Module: Philiprehberger::RateLimiter::StatsTracking

Included in:
FixedWindow, SlidingWindow, TokenBucket
Defined in:
lib/philiprehberger/rate_limiter/stats_tracking.rb

Instance Method Summary collapse

Instance Method Details

#allow!(key, weight: 1) ⇒ true

Like allow? but raises RateLimitExceeded when rejected.

Parameters:

  • key (Symbol, String)

    the rate limit key

  • weight (Integer) (defaults to: 1)

    tokens to consume

Returns:

  • (true)

Raises:



35
36
37
38
39
# File 'lib/philiprehberger/rate_limiter/stats_tracking.rb', line 35

def allow!(key, weight: 1)
  return true if allow?(key, weight: weight)

  raise RateLimitExceeded, key
end

#block(key = :default, timeout: nil, weight: 1) ⇒ Boolean

Block until capacity is available, then consume it.

Loops on #retry_after, sleeping between checks until #allow? succeeds. When timeout is given, returns false if the budget elapses before capacity frees up.

Parameters:

  • key (Symbol, String) (defaults to: :default)

    the rate limit key

  • timeout (Float, nil) (defaults to: nil)

    max seconds to wait (nil = wait forever)

  • weight (Integer) (defaults to: 1)

    tokens/slots to consume

Returns:

  • (Boolean)

    true once acquired, false if the timeout elapsed



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/philiprehberger/rate_limiter/stats_tracking.rb', line 58

def block(key = :default, timeout: nil, weight: 1)
  deadline = timeout ? monotonic_time + timeout : nil
  loop do
    return true if allow?(key, weight: weight)

    wait = retry_after(key)
    wait = 0.01 if wait <= 0.0

    if deadline
      budget = deadline - monotonic_time
      return false if budget <= 0.0

      wait = budget if wait > budget
    end

    sleep(wait)
  end
end

#keysArray<String>

Return all currently tracked keys.

Returns:

  • (Array<String>)


44
45
46
# File 'lib/philiprehberger/rate_limiter/stats_tracking.rb', line 44

def keys
  @mutex.synchronize { @store.keys }
end

#on_reject(&block) ⇒ Object



10
11
12
13
# File 'lib/philiprehberger/rate_limiter/stats_tracking.rb', line 10

def on_reject(&block)
  @mutex.synchronize { @on_reject_callback = block }
  self
end

#stats(key) ⇒ Object



6
7
8
# File 'lib/philiprehberger/rate_limiter/stats_tracking.rb', line 6

def stats(key)
  @mutex.synchronize { fetch_stats(key).dup }
end

#throttle(key, weight: 1) { ... } ⇒ Hash

Execute a block if allowed, returning the result in a hash.

Parameters:

  • key (Symbol, String)

    the rate limit key

  • weight (Integer) (defaults to: 1)

    tokens to consume

Yields:

  • the block to execute when allowed

Returns:

  • (Hash)

    { allowed: true, value: result } or { allowed: false, value: nil }



21
22
23
24
25
26
27
# File 'lib/philiprehberger/rate_limiter/stats_tracking.rb', line 21

def throttle(key, weight: 1, &block)
  if allow?(key, weight: weight)
    { allowed: true, value: block.call }
  else
    { allowed: false, value: nil }
  end
end