pub enum Tracker<T: Time = SystemTime> {
// some variants omitted
}
Expand description
State for a single rate limit.
This tracks the state of a single rate limit. For example the rate limit for a particular IP.
This object is intentionally small and cheap so that it can be created for fine-grained tracking.
Implementations§
Source§impl<T: Time> Tracker<T>
impl<T: Time> Tracker<T>
Sourcepub fn full() -> Self
pub fn full() -> Self
Create a tracker that is full.
This creates a tracker that has it’s full burst capacity available.
Sourcepub fn overfull(capacity: u32) -> Self
pub fn overfull(capacity: u32) -> Self
Create a tracker that is overfull.
This tracker is not only full to its full burst capacity but also has extra capacity. This extra capacity will be consumed before dipping into the burst
quota and regular rate limiting. This tracker will not fill itself up to the overfull state again, once the extra capacity is consumed it behaves as a regular tracker. (If you want it to fill further use a different crate::Config
which has a larger burst capacity.)
Note: This allows for requests up to crate::Config::burst + capacity
to be fulfilled until the overfull capacity runs out.
Sourcepub fn unlimited() -> Self
pub fn unlimited() -> Self
Create a tracker that is unlimited.
This can be used to disable rate limiting for a specific tracker. It is semantically identical to being overfull with infinite capacity.
Sourcepub fn new_at(now: T) -> Self
👎Deprecated: Use empty_at()
which has a more descriptive name.
pub fn new_at(now: T) -> Self
empty_at()
which has a more descriptive name.Create a tracker that starts at the provided time.
This is an alias for Tracker::empty_at()
.
Sourcepub fn empty_at(now: T) -> Self
pub fn empty_at(now: T) -> Self
Create a tracker that was empty at the provided time.
This means that the bucket will be empty at the indicated time and will fill starting from there. Note that this is not what you want for an limit that hasn’t been used for a while and cleaned from the DB. For that case you want Tracker::default()
.
Note that if now
is in the future it is possible to create a tracker that is empty and will remain empty until that point. This may be seen as a sort of “overdrawn” bucket that will take filling to return to zero.
Sourcepub fn with_capacity_at(config: &Config<T>, capacity: u32, now: T) -> Self
pub fn with_capacity_at(config: &Config<T>, capacity: u32, now: T) -> Self
Create a tracker that has the specified capacity at the specified time.
Sourcepub fn with_limited_capacity_at(
config: &Config<T>,
capacity: u32,
now: T,
) -> Self
pub fn with_limited_capacity_at( config: &Config<T>, capacity: u32, now: T, ) -> Self
Create a tracker that has the specified capacity up to the burst size.
This will never overfill the tracker, instead saturating at the burst capacity. If you want to allow overfilling use Tracker::with_capacity_at()
.
Sourcepub fn capacity_at(&self, config: &Config<T>, now: T) -> u32
pub fn capacity_at(&self, config: &Config<T>, now: T) -> u32
Returns the tokens available at the specified time.
Note that history is not stored, this is just extrapolating from the current state. So if config.rate
is 1/s advancing now
by 10s will raise the capacity by 10 (up to config.burst
), moving now
back 10s will lower the capacity by 10 (down to 0). Moving now
past the time where tokens were acquired will not restore those tokens to the capacity as returned by this function.
Sourcepub fn acquire_at(
&mut self,
config: &Config<T>,
count: u32,
now: T,
) -> Result<(), Denied<T>>
pub fn acquire_at( &mut self, config: &Config<T>, count: u32, now: T, ) -> Result<(), Denied<T>>
Attempt to acquire count
tokens from the rate limiter.
If the requested number of tokens are available the state is updated and Ok(())
is returned. Otherwise an error describing the issue is returned.
Warning: To save memory a Tracker does not remember its crate::Config. This means that you can switch the config
argument between calls on the same Tracker. This is not recommended as it is not immediately obvious what the result will be but is completely supported. The only guarantee provided is that the new rate limit will (eventually) take effect. The logical state of the Tracker when this occurs may be surprising. For example a large “burst” config may be immediately filled or a new low “rate” may result in a previous “burst” capacity disappearing. The exact behaviour is not guaranteed to be stable. If you want a specific behaviour it is best to extract the information you want with the old config and create a fresh tracker using the constructor functions to produce a tracker in the state that you expect.
Sourcepub fn acquire_range_at(
&mut self,
config: &Config<T>,
request: RangeInclusive<u32>,
now: T,
) -> Result<u32, Denied<T>>
pub fn acquire_range_at( &mut self, config: &Config<T>, request: RangeInclusive<u32>, now: T, ) -> Result<u32, Denied<T>>
Acquire tokens from the tracker.
Acquires at least request.start()
tokens but no more than request.end()
.
Returns the number of tokens acquired.
If the available capacity is less than request.start()
Err(crate::Denied::TooEarly)
is returned.
If request.start()
is zero than this call always succeeds.
Sourcepub fn acquire_up_to_at(
&mut self,
config: &Config<T>,
count: u32,
now: T,
) -> Result<u32, TooEarly<T>>
👎Deprecated: Use acquire_up_to_at_2.
pub fn acquire_up_to_at( &mut self, config: &Config<T>, count: u32, now: T, ) -> Result<u32, TooEarly<T>>
Acquire up to count
tokens from the rate limiter.
Returns the number of tokens actually acquired. Fails if no tokens were acquired. If 0 is acceptable use .unwrap_or(0)
to explicitly waive the error.
As a special case requesting 0
will always succeed with Ok(0)
.
WARNING: This function will return Ok(0)
on disabled configs. If you are using disabled configs please migrate to [Tracker::acquire_up_to_at_2()
][Tacker::acquire_up_to_at_2()] for a proper error.
Equivalent to Tracker::acquire_range_at(config, 1..=count, now)
.
Sourcepub fn acquire_up_to_at_2(
&mut self,
config: &Config<T>,
count: u32,
now: T,
) -> Result<u32, Denied<T>>
pub fn acquire_up_to_at_2( &mut self, config: &Config<T>, count: u32, now: T, ) -> Result<u32, Denied<T>>
Acquire up to count
tokens from the rate limiter.
Returns the number of tokens actually acquired. Fails if no tokens were acquired. If 0 is acceptable use .unwrap_or(0)
to explicitly waive the error.
As a special case requesting 0
will always succeed with Ok(0)
.
Equivalent to Tracker::acquire_range_at(config, 1..=count, now)
.
Sourcepub fn force_acquire_at(&mut self, config: &Config<T>, count: u32, now: T)
pub fn force_acquire_at(&mut self, config: &Config<T>, count: u32, now: T)
Force acquire from the rate limiter.
This can not fail, the capacity can go “below zero” using this method. For example if the Config replenishes at 1 token per second and there are 2 tokens available, then acquiring 5 tokens will result in a capacity of 0 but requires 4 seconds for the next token to become available.
Note: While Tracker::capacity()
will never report negative values the time reported in TooEarly.available_at()
will accurately reflect when the request will become available.
Sourcepub fn add_capacity_at(&mut self, config: &Config<T>, tokens: u32, now: T)
pub fn add_capacity_at(&mut self, config: &Config<T>, tokens: u32, now: T)
Add capacity.
This adds some number of tokens to the tracker.
Warning: This method will overfill the tracker. If this is not desired use add_limited_capacity_at()
.
Note: When this method overfills the tracker any existing progress toward the next token is lost. For example if a 1s token interval was 1ns away from fully filling, adding 1 capacity will effectively add that 1ns of time, whereas if it was 999ms away from full it will add 999ms. This also means that t.add_capacity_at(c, 1, now); t.acquire_at(c, 1, now)
will not always leave t
in the same state as if the additional fills the tracker the incremental progress will be reset.
Sourcepub fn add_limited_capacity_at(
&mut self,
config: &Config<T>,
tokens: u32,
_now: T,
)
pub fn add_limited_capacity_at( &mut self, config: &Config<T>, tokens: u32, _now: T, )
Add capacity without overfilling.
This adds some number of tokens to the tracker without allowing it to overfill.
Note: If overfilling is desired use add_capacity()
.
Sourcepub fn simplify_at(&mut self, config: &Config<T>, now: T) -> bool
pub fn simplify_at(&mut self, config: &Config<T>, now: T) -> bool
Attempts to minimize the state.
If a rate limit hasn’t been used in a long time the bucket will be full and the state can be simplified.
Returns true
if the state is “simple” and equivalent to Tracker::default()
. If this occurs you don’t need to store the state and can use the default state if needed again.
Source§impl<T: TimeNow> Tracker<T>
impl<T: TimeNow> Tracker<T>
Sourcepub fn empty() -> Self
pub fn empty() -> Self
Create a tracker that starts empty at the current time.
Equivalent to [Tracker::empty_at(T::now())
][Tracker::empty_at()].
Sourcepub fn with_capacity(config: &Config<T>, capacity: u32) -> Self
pub fn with_capacity(config: &Config<T>, capacity: u32) -> Self
Create a tracker that has the specified capacity.
Equivalent to Tracker::with_capacity_at(config, capacity, T::now())
.
Sourcepub fn with_limited_capacity(config: &Config<T>, capacity: u32) -> Self
pub fn with_limited_capacity(config: &Config<T>, capacity: u32) -> Self
Create a tracker that has the specified capacity without overfilling.
Equivalent to Tracker::with_limited_capacity_at(config, capacity, T::now())
.
Sourcepub fn capacity(&self, config: &Config<T>) -> u32
pub fn capacity(&self, config: &Config<T>) -> u32
Returns the tokens currently available.
Equivalent to Tracker::capacity_at(T::now())
.
Sourcepub fn acquire(
&mut self,
config: &Config<T>,
count: u32,
) -> Result<(), Denied<T>>
pub fn acquire( &mut self, config: &Config<T>, count: u32, ) -> Result<(), Denied<T>>
Attempt to acquire count
tokens from the rate limiter at the current time
Equivalent to Tracker::acquire_at(config, count, T::now())
.
Sourcepub fn acquire_range(
&mut self,
config: &Config<T>,
request: RangeInclusive<u32>,
) -> Result<u32, Denied<T>>
pub fn acquire_range( &mut self, config: &Config<T>, request: RangeInclusive<u32>, ) -> Result<u32, Denied<T>>
Acquire tokens from the tracker.
Equivalent to Tracker::acquire_range_at(config, request, T::now())
.
Sourcepub fn acquire_up_to(
&mut self,
config: &Config<T>,
count: u32,
) -> Result<u32, TooEarly<T>>
👎Deprecated: Use acquire_up_to_2.
pub fn acquire_up_to( &mut self, config: &Config<T>, count: u32, ) -> Result<u32, TooEarly<T>>
Acquire up to count
tokens from the rate limiter at the current time.
Equivalent to Tracker::acquire_up_to_at(config, count, T::now())
.
Sourcepub fn acquire_up_to_2(
&mut self,
config: &Config<T>,
count: u32,
) -> Result<u32, Denied<T>>
pub fn acquire_up_to_2( &mut self, config: &Config<T>, count: u32, ) -> Result<u32, Denied<T>>
Acquire up to count
tokens from the rate limiter at the current time.
Equivalent to Tracker::acquire_up_to_at_2(config, count, T::now())
.
Sourcepub fn force_acquire(&mut self, config: &Config<T>, count: u32)
pub fn force_acquire(&mut self, config: &Config<T>, count: u32)
Force acquire tokens at the current time.
Equivalent to Tracker::force_acquire_at(config, count, T::now())
.
Sourcepub fn add_capacity(&mut self, config: &Config<T>, tokens: u32)
pub fn add_capacity(&mut self, config: &Config<T>, tokens: u32)
Add capacity.
Equivalent to Tracker::add_capacity_at(config, count, tokens, T::now())
.
Sourcepub fn add_limited_capacity(&mut self, config: &Config<T>, tokens: u32)
pub fn add_limited_capacity(&mut self, config: &Config<T>, tokens: u32)
Add capacity without overfilling.
Equivalent to Tracker::add_limited_capacity_at(config, count, tokens, T::now())
.
Sourcepub fn simplify(&mut self, config: &Config<T>) -> bool
pub fn simplify(&mut self, config: &Config<T>) -> bool
Attempts to minimize the state at the current time.
Equivalent to Tracker::simplify_at(config, T::now())
.