Class: Datadog::Sampling::TokenBucket

Inherits:
RateLimiter show all
Defined in:
lib/ddtrace/sampling/rate_limiter.rb

Overview

Implementation of the Token Bucket metering algorithm for rate limiting.

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rate, max_tokens = rate) ⇒ TokenBucket

Returns a new instance of TokenBucket.

Parameters:

  • rate (Numeric)

    Allowance rate, in units per second if rate is negative, always allow if rate is zero, never allow

  • max_tokens (Numeric) (defaults to: rate)

    Limit of available tokens



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ddtrace/sampling/rate_limiter.rb', line 35

def initialize(rate, max_tokens = rate)
  @rate = rate
  @max_tokens = max_tokens

  @tokens = max_tokens
  @total_messages = 0
  @conforming_messages = 0
  @prev_conforming_messages = nil
  @prev_total_messages = nil
  @current_window = nil

  @last_refill = Utils::Time.get_time
end

Instance Attribute Details

#max_tokensObject (readonly)

Returns the value of attribute max_tokens.



29
30
31
# File 'lib/ddtrace/sampling/rate_limiter.rb', line 29

def max_tokens
  @max_tokens
end

#rateObject (readonly)

Returns the value of attribute rate.



29
30
31
# File 'lib/ddtrace/sampling/rate_limiter.rb', line 29

def rate
  @rate
end

Instance Method Details

#allow?(size) ⇒ Boolean

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 from the bucket.

Returns:

  • (Boolean)

    +true+ if message conforms with current bucket limit



58
59
60
61
62
# File 'lib/ddtrace/sampling/rate_limiter.rb', line 58

def allow?(size)
  allowed = should_allow?(size)
  update_rate_counts(allowed)
  allowed
end

#available_tokensNumeric

Returns number of tokens currently available.

Returns:

  • (Numeric)

    number of tokens currently available



92
93
94
# File 'lib/ddtrace/sampling/rate_limiter.rb', line 92

def available_tokens
  @tokens
end

#current_window_rateFloat

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

Returns +1.0+ when no messages have been checked yet.

Returns:

  • (Float)

    Conformance ratio, between +[0,1]+



85
86
87
88
89
# File 'lib/ddtrace/sampling/rate_limiter.rb', line 85

def current_window_rate
  return 1.0 if @total_messages.zero?

  @conforming_messages.to_f / @total_messages
end

#effective_rateFloat

Ratio of 'conformance' per 'total messages' checked averaged for the past 2 buckets

Returns +1.0+ when no messages have been checked yet.

Returns:

  • (Float)

    Conformance ratio, between +[0,1]+



70
71
72
73
74
75
76
77
# File 'lib/ddtrace/sampling/rate_limiter.rb', line 70

def effective_rate
  return 0.0 if @rate.zero?
  return 1.0 if @rate < 0 || @total_messages.zero?

  return current_window_rate if @prev_conforming_messages.nil? || @prev_total_messages.nil?

  (@conforming_messages.to_f + @prev_conforming_messages.to_f) / (@total_messages + @prev_total_messages)
end