class ActionLimiter::TokenBucket

Implementes a Token Bucket algorithm for rate limiting.

@author Maddie Schipper @since 0.1.0

Constants

Bucket

Attributes

namespace[R]

The bucket namespace. The value will be prefixed to any bucket’s name

@return [String] The prefix

period[R]

The period length for the bucket in seconds

@return [Integer] The specified period

size[R]

The allowed size of the bucket

@return [Integer] The size of the bucket

Public Class Methods

new(period:, size:, namespace: nil) click to toggle source

Initialize the token bucket instance

@param period [#to_i] The value used to determine the bucket’s period @param size [#to_i] The maximum number of tokens in the bucket for the given period @param namespace [nil, to_s] Value to prefix all

# File lib/action_limiter/token_bucket.rb, line 40
def initialize(period:, size:, namespace: nil)
  @period = period.to_i
  @size = size.to_i
  @namespace = namespace&.to_s || 'action_limiter/token_bucket'
  @script_hash = ActionLimiter::RedisProvider.connection_pool.with do |connection|
    connection.script(:load, ActionLimiter::SCRIPTS.fetch(:token_bucket))
  end
end

Public Instance Methods

increment(bucket, time) click to toggle source

@private

# File lib/action_limiter/token_bucket.rb, line 62
def increment(bucket, time)
  ActionLimiter.instrument('action_limiter.token_bucket.increment') do
    ActionLimiter::RedisProvider.connection_pool.with do |connection|
      time_stamp = time.to_f
      bucket_key = "#{namespace}/#{bucket}"
      value = connection.evalsha(@script_hash, [bucket_key], [period.to_s, time_stamp.to_s])
      Bucket.new(bucket, value)
    end
  end
end
limited?(bucket, time: Time.now) click to toggle source

Predicate for checking if the specified bucket name is incremented

@param bucket [String] The name of the bucket to check @param time [Time] The time the check will occur

@return [true, false] The limiting status of the bucket

# File lib/action_limiter/token_bucket.rb, line 56
def limited?(bucket, time: Time.now)
  increment(bucket, time).value > size
end