glimit/bucket
This module contains pure token-bucket functions used by the rate limiter.
Types
The state of a single token bucket.
pub type BucketState {
BucketState(
max_token_count: Int,
token_rate: Int,
token_count: Float,
last_update: option.Option(Int),
)
}
Constructors
-
BucketState( max_token_count: Int, token_rate: Int, token_count: Float, last_update: option.Option(Int), )Arguments
- max_token_count
-
The maximum number of tokens.
- token_rate
-
The rate of token generation per second.
- token_count
-
The number of tokens available.
- last_update
-
Monotonic timestamp (milliseconds) of the last time the bucket was updated.
A pluggable storage backend for distributed rate limiting.
All token bucket logic is handled by glimit — store adapters only need to implement simple lock-and-get / set-and-unlock operations on string-keyed bucket state.
lock_and_get: Acquire an exclusive lock for the key and retrieve its bucket state. ReturnOk(None)for a new/missing key. If the lock cannot be acquired, returnError(Nil).set_and_unlock: Persist bucket state with a TTL in seconds for automatic expiry, then release the lock.unlock: Release the lock without writing. Used on error paths when there is nothing to persist.
When lock_and_get fails, the rate limiter fails open (allows the
request).
pub type Store {
Store(
lock_and_get: fn(String) -> Result(
option.Option(BucketState),
Nil,
),
set_and_unlock: fn(String, BucketState, Int) -> Result(
Nil,
Nil,
),
unlock: fn(String) -> Result(Nil, Nil),
)
}
Constructors
-
Store( lock_and_get: fn(String) -> Result( option.Option(BucketState), Nil, ), set_and_unlock: fn(String, BucketState, Int) -> Result(Nil, Nil), unlock: fn(String) -> Result(Nil, Nil), )
Values
pub fn compute_ttl(b: BucketState) -> Int
Compute a TTL in seconds for the bucket state.
The TTL is based on the time it takes to fully refill from empty, with a minimum of 60 seconds.
pub fn from_pairs(
pairs: List(#(String, String)),
) -> Result(BucketState, Nil)
Parse a BucketState from a list of string key-value pairs.
This is the inverse of to_pairs. Returns Error(Nil) if any required
field is missing or cannot be parsed.
pub fn hit(
state: BucketState,
now: Int,
) -> #(Result(Nil, Nil), BucketState)
Hit the bucket: refill, then try to consume one token.
Returns #(Ok(Nil), new_state) on success,
#(Error(Nil), new_state) when rate-limited.
pub fn is_full(state: BucketState, now: Int) -> Bool
Returns True if the bucket is full after refilling.
pub fn new(
max_token_count: Int,
token_rate: Int,
) -> Result(BucketState, Nil)
Create a new bucket state.
Returns Error(Nil) if max_token_count or token_rate are not positive.
pub fn refill(state: BucketState, now: Int) -> BucketState
Refill the bucket based on elapsed time.
pub fn to_pairs(state: BucketState) -> List(#(String, String))
Convert a BucketState to a list of string key-value pairs.
Useful for serializing bucket state into external stores (e.g. Redis HSET).
Keys: "tc" (token count), "lu" (last update), "mt" (max tokens), "tr" (token rate).