class RateLimit::Htb::Bucket

Public Class Methods

new(rate, parent = nil) click to toggle source

Attributes

  • rate - Amount of tokens generated every second.

  • parent - Parent of this bucket. Any tokens taken from this bucket will also be taken from parent. When a parent is specified the rate of this bucket will be between the rate of this bucket and the rate of the parent. The parent bucket should have a larger rate than their children.

# File lib/rate_limit/htb.rb, line 54
def initialize(rate, parent = nil)
  @lock = Monitor.new
  @rate = rate || 0
  @bucket_size = rate
  @parent = parent
  @tokens = rate
  @last_update_timestamp = Time.now
end

Public Instance Methods

blocking_take(amount) click to toggle source

This method takes the specified amount of tokens from the bucket and blocks execution until it was successful.

This method tries to be smart about the amount of time it waits. It will wait the minimum time it takes to replenish enough tokens.

# File lib/rate_limit/htb.rb, line 86
def blocking_take(amount)
  # Try to take amount tokens from this bucket or wait for the tokens to replenish
  # do this until we could get the amount of tokens we wanted
  until take amount
    duration = amount.to_f / rate # rate is a method
    #puts "sleeping for #{duration}"
    sleep duration
  end
end
take(amount) click to toggle source

Take the specified amount of tokens from this bucket

If you want your code to block execution until it could take the specified amount of tokens use blocking_take instead.

  • Returns :

    • true if the amount of tokens could be taken from this bucket or a parent.

# File lib/rate_limit/htb.rb, line 70
def take(amount)
  @lock.synchronize do
    replenish

    could_take = can_take? amount
    account amount if could_take

    could_take
  end
end

Protected Instance Methods

account(amount) click to toggle source
# File lib/rate_limit/htb.rb, line 113
def account(amount)
  @lock.synchronize do
    @tokens = @tokens - amount
    @parent.account amount if @parent
  end
end
can_take?(amount) click to toggle source
# File lib/rate_limit/htb.rb, line 109
def can_take?(amount)
  @tokens >= amount || (@parent && @parent.can_take?(amount))
end
rate() click to toggle source
# File lib/rate_limit/htb.rb, line 120
def rate
  return @rate if @rate != 0
  return @parent.rate if @parent

  raise 'NO Bucket in this hierachie has a Limit other than zero!!'
end
replenish(timestamp = Time.now) click to toggle source
# File lib/rate_limit/htb.rb, line 98
def replenish(timestamp = Time.now)
  @lock.synchronize do
    @parent.replenish timestamp if @parent

    elapsed = timestamp - @last_update_timestamp
    @tokens = [@bucket_size, @tokens + @rate * elapsed].min

    @last_update_timestamp = timestamp
  end
end