class XRay::Reservoir

Centralized thread-safe reservoir which holds fixed sampling quota for the current instance, borrowed count and TTL.

Attributes

quota[R]
ttl[R]

Public Class Methods

new() click to toggle source
# File lib/aws-xray-sdk/sampling/reservoir.rb, line 10
def initialize
  @quota = nil
  @ttl = nil

  @this_sec = 0
  @taken_this_sec = 0
  @borrowed_this_sec = 0

  @report_interval = 1
  @report_elapsed = 0

  @lock = Mutex.new
end

Public Instance Methods

borrow_or_take(now, borrowable) click to toggle source

Decide whether to borrow or take one quota from the reservoir. Return `false` if it can neither borrow nor take. This method is thread-safe.

# File lib/aws-xray-sdk/sampling/reservoir.rb, line 27
def borrow_or_take(now, borrowable)
  @lock.synchronize do
    reset_new_sec(now)
    # Don't borrow if the quota is available and fresh.
    if quota_fresh?(now)
      return SamplingDecision::NOT_SAMPLE if @taken_this_sec >= @quota
      @taken_this_sec += 1
      return SamplingDecision::TAKE
    end

    # Otherwise try to borrow if the quota is not present or expired.
    if borrowable
      return SamplingDecision::NOT_SAMPLE if @borrowed_this_sec >= 1
      @borrowed_this_sec += 1
      return SamplingDecision::BORROW
    end

    # Cannot sample if quota expires and cannot borrow
    SamplingDecision::NOT_SAMPLE
  end
end
load_target_info(quota:, ttl:, interval:) click to toggle source
# File lib/aws-xray-sdk/sampling/reservoir.rb, line 49
def load_target_info(quota:, ttl:, interval:)
  @quota = quota unless quota.nil?
  @ttl = ttl.to_i unless ttl.nil?
  @interval = interval / 10 unless interval.nil?
end
time_to_report?() click to toggle source
# File lib/aws-xray-sdk/sampling/reservoir.rb, line 55
def time_to_report?
  if @report_elapsed + 1 >= @report_interval
    @report_elapsed = 0
    true
  else
    @report_elapsed += 1
    false
  end
end

Private Instance Methods

quota_fresh?(now) click to toggle source
# File lib/aws-xray-sdk/sampling/reservoir.rb, line 75
def quota_fresh?(now)
  @quota && @quota >= 0 && @ttl && @ttl >= now
end
reset_new_sec(now) click to toggle source

Reset the counter if now enters a new one-second window

# File lib/aws-xray-sdk/sampling/reservoir.rb, line 68
def reset_new_sec(now)
  return if now == @this_sec
  @taken_this_sec = 0
  @borrowed_this_sec = 0
  @this_sec = now
end