class Datadog::Sampling::TokenBucket

Implementation of the Token Bucket metering algorithm for rate limiting.

@see en.wikipedia.org/wiki/Token_bucket Token bucket

Attributes

max_tokens[R]
rate[R]

Public Class Methods

new(rate, max_tokens = rate) click to toggle source

@param rate [Numeric] Allowance rate, in units per second

if rate is negative, always allow
if rate is zero, never allow

@param max_tokens [Numeric] Limit of available tokens

# File lib/ddtrace/sampling/rate_limiter.rb, line 34
def initialize(rate, max_tokens = rate)
  @rate = rate
  @max_tokens = max_tokens

  @tokens = max_tokens
  @total_messages = 0
  @conforming_messages = 0
  @last_refill = Utils::Time.get_time
end

Public Instance Methods

allow?(size) click to toggle source

Checks if a message of provided size conforms with the current bucket limit.

If it does, return true and remove size tokens from the bucket. If it does not, return false without affecting the tokens form the bucket.

@return [Boolean] true if message conforms with current bucket limit

# File lib/ddtrace/sampling/rate_limiter.rb, line 53
def allow?(size)
  return false if @rate.zero?
  return true if @rate < 0

  refill_since_last_message

  increment_total_count

  return false if @tokens < size

  increment_conforming_count

  @tokens -= size

  true
end
available_tokens() click to toggle source

@return [Numeric] number of tokens currently available

# File lib/ddtrace/sampling/rate_limiter.rb, line 84
def available_tokens
  @tokens
end
effective_rate() click to toggle source

Ratio of 'conformance' per 'total messages' checked on this bucket.

Returns 1.0 when no messages have been checked yet.

@return [Float] Conformance ratio, between +[0,1]+

# File lib/ddtrace/sampling/rate_limiter.rb, line 76
def effective_rate
  return 0.0 if @rate.zero?
  return 1.0 if @rate < 0 || @total_messages.zero?

  @conforming_messages.to_f / @total_messages
end

Private Instance Methods

increment_conforming_count() click to toggle source
# File lib/ddtrace/sampling/rate_limiter.rb, line 108
def increment_conforming_count
  @conforming_messages += 1
end
increment_total_count() click to toggle source
# File lib/ddtrace/sampling/rate_limiter.rb, line 104
def increment_total_count
  @total_messages += 1
end
refill_since_last_message() click to toggle source
# File lib/ddtrace/sampling/rate_limiter.rb, line 90
def refill_since_last_message
  now = Utils::Time.get_time
  elapsed = now - @last_refill

  refill_tokens(@rate * elapsed)

  @last_refill = now
end
refill_tokens(size) click to toggle source
# File lib/ddtrace/sampling/rate_limiter.rb, line 99
def refill_tokens(size)
  @tokens += size
  @tokens = @max_tokens if @tokens > @max_tokens
end