Class: ActionLimiter::TokenBucket

Inherits:
Object
  • Object
show all
Defined in:
lib/action_limiter/token_bucket.rb

Overview

Implementes a Token Bucket algorithm for rate limiting.

Author:

  • Maddie Schipper

Since:

  • 0.1.0

Defined Under Namespace

Classes: Bucket

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(period:, size:, namespace: nil) ⇒ TokenBucket

Initialize the token bucket instance

Parameters:

  • period (#to_i)

    The value used to determine the bucket’s period

  • size (#to_i)

    The maximum number of tokens in the bucket for the given period

  • namespace (nil, #to_s) (defaults to: nil)

    Value to prefix all

Since:

  • 0.1.0



42
43
44
45
46
# File 'lib/action_limiter/token_bucket.rb', line 42

def initialize(period:, size:, namespace: nil)
  @period = period.to_i
  @size = size.to_i
  @namespace = namespace&.to_s || 'action_limiter/token_bucket'
end

Instance Attribute Details

#namespaceString (readonly)

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

Returns:

  • (String)

    The prefix

Since:

  • 0.1.0



34
35
36
# File 'lib/action_limiter/token_bucket.rb', line 34

def namespace
  @namespace
end

#periodInteger (readonly)

The period length for the bucket in seconds

Returns:

  • (Integer)

    The specified period

Since:

  • 0.1.0



22
23
24
# File 'lib/action_limiter/token_bucket.rb', line 22

def period
  @period
end

#sizeInteger (readonly)

The allowed size of the bucket

Returns:

  • (Integer)

    The size of the bucket

Since:

  • 0.1.0



28
29
30
# File 'lib/action_limiter/token_bucket.rb', line 28

def size
  @size
end

Instance Method Details

#delete(bucket) ⇒ void

This method returns an undefined value.

Delete a bucket’s current value

Parameters:

  • bucket (String)

    The name of the bucket to delete

Since:

  • 0.1.0



65
66
67
68
69
70
71
# File 'lib/action_limiter/token_bucket.rb', line 65

def delete(bucket)
  ActionLimiter.instrument('action_limiter.token_bucket.reset') do
    ActionLimiter.with_redis_connection do |connection|
      connection.del(bucket_key(bucket))
    end
  end
end

#increment_and_return_bucket(bucket, time) ⇒ Object

Since:

  • 0.1.0



75
76
77
78
79
80
81
82
# File 'lib/action_limiter/token_bucket.rb', line 75

def increment_and_return_bucket(bucket, time)
  ActionLimiter.instrument('action_limiter.token_bucket.increment') do
    ActionLimiter.with_redis_connection do |connection|
      value = connection.evalsha(script_hash, [bucket_key(bucket)], [period.to_s, time.to_f.to_s])
      Bucket.new(name: bucket, value: value, max_size: size, period: period)
    end
  end
end

#limited?(bucket, time: Time.now) ⇒ true, false

Predicate for checking if the specified bucket name is incremented

Parameters:

  • bucket (String)

    The name of the bucket to check

  • time (Time) (defaults to: Time.now)

    The time the check will occur

Returns:

  • (true, false)

    The limiting status of the bucket

Since:

  • 0.1.0



55
56
57
# File 'lib/action_limiter/token_bucket.rb', line 55

def limited?(bucket, time: Time.now)
  increment_and_return_bucket(bucket, time).value > size
end