Sha256: 3f2bbdd8c3180316d144336c3b55e9f858d2dd87306a20ee162522c652e4a368

Contents?: true

Size: 1.82 KB

Versions: 21

Compression:

Stored size: 1.82 KB

Contents

# encoding: UTF-8

module Vines

  # The token bucket algorithm is useful for rate limiting.
  # Before an operation can be completed, a token is taken from
  # the bucket.  If no tokens are available, the operation fails.
  # The bucket is refilled with tokens at the maximum allowed rate
  # of operations.
  class TokenBucket

    # Create a full bucket with `capacity` number of tokens to be filled
    # at the given rate of tokens/second.
    #
    # capacity - The Fixnum maximum number of tokens the bucket can hold.
    # rate     - The Fixnum number of tokens per second at which the bucket is
    #            refilled.
    def initialize(capacity, rate)
      raise ArgumentError.new('capacity must be > 0') unless capacity > 0
      raise ArgumentError.new('rate must be > 0') unless rate > 0
      @capacity = capacity
      @tokens = capacity
      @rate = rate
      @timestamp = Time.new
    end

    # Remove tokens from the bucket if it's full enough. There's no way, or
    # need, to add tokens to the bucket. It refills over time.
    #
    # tokens - The Fixnum number of tokens to attempt to take from the bucket.
    #
    # Returns true if the bucket contains enough tokens to take, false if the
    # bucket isn't full enough to satisy the request.
    def take(tokens)
      raise ArgumentError.new('tokens must be > 0') unless tokens > 0
      tokens <= fill ? @tokens -= tokens : false
    end

    private

    # Add tokens to the bucket at the `rate` provided in the constructor. This
    # fills the bucket slowly over time.
    #
    # Returns the Fixnum number of tokens left in the bucket.
    def fill
      if @tokens < @capacity
        now = Time.new
        @tokens += (@rate * (now - @timestamp)).round
        @tokens = @capacity if @tokens > @capacity
        @timestamp = now
      end
      @tokens
    end
  end
end

Version data entries

21 entries across 21 versions & 4 rubygems

Version Path
diaspora-vines-0.2.0.develop.4 lib/vines/token_bucket.rb
diaspora-vines-0.2.0.develop.3 lib/vines/token_bucket.rb
diaspora-vines-0.2.0.develop.2 lib/vines/token_bucket.rb
diaspora-vines-0.2.0.develop.1 lib/vines/token_bucket.rb
diaspora-vines-0.1.28 lib/vines/token_bucket.rb
lygneo-vines-0.1.5 lib/vines/token_bucket.rb
lygneo-vines-0.1.1 lib/vines/token_bucket.rb
diaspora-vines-0.1.27 lib/vines/token_bucket.rb
diaspora-vines-0.1.26 lib/vines/token_bucket.rb
diaspora-vines-0.1.25 lib/vines/token_bucket.rb
diaspora-vines-0.1.24 lib/vines/token_bucket.rb
vines-0.4.10 lib/vines/token_bucket.rb
diaspora-vines-0.1.22 lib/vines/token_bucket.rb
diaspora-vines-0.1.21 lib/vines/token_bucket.rb
diaspora-vines-0.1.2 lib/vines/token_bucket.rb
vines-0.4.9 lib/vines/token_bucket.rb
vines-0.4.8 lib/vines/token_bucket.rb
vines-0.4.7 lib/vines/token_bucket.rb
vines-0.4.6 lib/vines/token_bucket.rb
vinesmod-0.4.5.2 lib/vines/token_bucket.rb