time
is the reference time that other time accepting functions will use when
they adjust now
. It is almost always correct to set this to Time.now.hopper_to_bucket_rate_per_sec
bounds the maximum rate at which tokens fall from
the hopper into the bucket where they can be taken.bucket_limit
bounds the number of tokens that the lower bucket can hold. This
corresponds to the maximum burst in a standard token bucket setup.in_flight_limit
bounds the number of tokens that can be in flight. This
corresponds to a running job limit/throttle.initial_hopper_level
sets the number of tokens placed into the hopper when the
Limiter
is created.initial_bucket_level
sets the number of tokens placed into the bucket when the
Limiter
is created. If this amount exceeds the bucket size it will be silently
limited to bucket_limit
.These tunables can be combined in several ways:
initial_hopper_level + initial_bucket_level
should be bounded and clients
hold tokens for the duration of their work.hopper_to_bucket_rate_per_sec
should be
infinite but in_flight_limit
should be bounded to the upper job rate.In all cases above throttling and rate limiting combine nicely when the unit of work
for both is the same (e.g. one token per message). If the unit of work is different
(e.g. rate limit base on a number of tokens equal to message size, but throttle base
on simple message count) then a single t
probably cannot be used to get the correct
behavior, and two instances should be used with tokens taken from both.
returns the earliest time when the requested number of tokens could possibly be
delivered. There is no guarantee that the requested number of tokens will actually
be available at this time. You must call try_take
to actually attempt to take the
tokens.
attempts to take the given number of tokens from the bucket. try_take t ~now n
succeeds iff in_bucket t ~now >= n
.
return the given number of tokens to the hopper. These tokens will fill the tokens
available to try_take
at the fill_rate
. Note that if return
is called on more
tokens then have actually been removed, this can cause the number of concurrent jobs
to exceed max_concurrent_jobs
.
Note that, due to rounding issues, one should only return precisely the number of tokens that were previously taken. Returning a sum of different values taken previously may or may not work precisely, depending on the specific floating point numbers used.