debian-mirror-gitlab/debian/gems-compat/jaeger-client-0.10.0/lib/jaeger/rate_limiter.rb
2019-03-14 13:21:19 +05:30

61 lines
2 KiB
Ruby

# frozen_string_literal: true
module Jaeger
# RateLimiter is based on leaky bucket algorithm, formulated in terms of a
# credits balance that is replenished every time check_credit() method is
# called (tick) by the amount proportional to the time elapsed since the
# last tick, up to the max_balance. A call to check_credit() takes a cost
# of an item we want to pay with the balance. If the balance exceeds the
# cost of the item, the item is "purchased" and the balance reduced,
# indicated by returned value of true. Otherwise the balance is unchanged
# and return false.
#
# This can be used to limit a rate of messages emitted by a service by
# instantiating the Rate Limiter with the max number of messages a service
# is allowed to emit per second, and calling check_credit(1.0) for each
# message to determine if the message is within the rate limit.
#
# It can also be used to limit the rate of traffic in bytes, by setting
# credits_per_second to desired throughput as bytes/second, and calling
# check_credit() with the actual message size.
class RateLimiter
def initialize(credits_per_second:, max_balance:)
@credits_per_second = credits_per_second
@max_balance = max_balance
@balance = max_balance
@last_tick = Time.now
end
def check_credit(item_cost)
update_balance
return false if @balance < item_cost
@balance -= item_cost
true
end
def update(credits_per_second:, max_balance:)
update_balance
@credits_per_second = credits_per_second
# The new balance should be proportional to the old balance
@balance = max_balance * @balance / @max_balance
@max_balance = max_balance
end
private
def update_balance
current_time = Time.now
elapsed_time = current_time - @last_tick
@last_tick = current_time
@balance += elapsed_time * @credits_per_second
return if @balance <= @max_balance
@balance = @max_balance
end
end
end