Enum Tracker

Source
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>

Source

pub fn full() -> Self

Create a tracker that is full.

This creates a tracker that has it’s full burst capacity available.

Source

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.

Source

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.

Source

pub fn new_at(now: T) -> Self

👎Deprecated: Use 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().

Source

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.

Source

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.

Source

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().

Source

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.

Source

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.

Source

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.

Source

pub 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.

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).

Source

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).

Source

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.

Source

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.

Source

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().

Source

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>

Source

pub fn empty() -> Self

Create a tracker that starts empty at the current time.

Equivalent to [Tracker::empty_at(T::now())][Tracker::empty_at()].

Source

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()).

Source

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()).

Source

pub fn capacity(&self, config: &Config<T>) -> u32

Returns the tokens currently available.

Equivalent to Tracker::capacity_at(T::now()).

Source

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()).

Source

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()).

Source

pub fn acquire_up_to( &mut self, config: &Config<T>, count: u32, ) -> Result<u32, TooEarly<T>>

👎Deprecated: Use acquire_up_to_2.

Acquire up to count tokens from the rate limiter at the current time.

Equivalent to Tracker::acquire_up_to_at(config, count, T::now()).

Source

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()).

Source

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()).

Source

pub fn add_capacity(&mut self, config: &Config<T>, tokens: u32)

Source

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()).

Source

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()).

Trait Implementations§

Source§

impl<T: Clone + Time> Clone for Tracker<T>

Source§

fn clone(&self) -> Tracker<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + Time> Debug for Tracker<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Time> Default for Tracker<T>

Source§

fn default() -> Self

Create a full tracker.

See [Tracker::full()] for more details.

Auto Trait Implementations§

§

impl<T> Freeze for Tracker<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Tracker<T>
where T: RefUnwindSafe,

§

impl<T> Send for Tracker<T>
where T: Send,

§

impl<T> Sync for Tracker<T>
where T: Sync,

§

impl<T> Unpin for Tracker<T>
where T: Unpin,

§

impl<T> UnwindSafe for Tracker<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.