Fast single node rate limiter implementing Token Bucket algorithm.
Summary
Functions
Returns a specification to start this module under a supervisor.
Checks if the request is allowed according to bucket parameters.
Differences from request/5
Checks if the request is allowed according to desired request rate.
Starts the process that manages ETS table for bucket data and periodically deletes idle buckets.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec raw_request( bucket :: any(), capacity :: pos_integer(), refill_ms :: pos_integer(), cost :: integer(), opts :: keyword() ) :: {:allow | :deny, tokens :: non_neg_integer(), :atomics.atomics_ref()}
Checks if the request is allowed according to bucket parameters.
Differences from request/5:
- direct control of bucket parameters (less ergonomic but more powerful)
- always returns remaining tokens
- supports variable cost
- supports negative cost, i.e. "refunds"
- because of token accounting refills the bucket on every call (eager
refill), while
request/5skips it for denied requests (lazy refill)
The bucket is initialized in full state. Every request will refill the bucket if needed and check if the new token amount with the cost applied is valid (not negative). Tokens above the capacity are discarded.
Returns {:allow, tokens, bucket_ref} or {:deny, tokens, bucket_ref}
where tokens is the number of remaining tokens in the bucket.
Arguments:
bucketbucket id, unique within its tablecapacitybucket capacityrefill_msnumber of tokens added to the bucket every millisecondcostnumber of tokens added or removed from the bucket for the current request to succeed, where negative values mean addition.
Supports same options as request/5
@spec request( bucket :: any(), window :: pos_integer(), window_requests :: pos_integer(), burst_requests :: pos_integer(), opts :: keyword() ) :: {:allow, bucket_requests :: non_neg_integer(), :atomics.atomics_ref()} | {:deny, timeout :: timeout(), :atomics.atomics_ref()}
Checks if the request is allowed according to desired request rate.
The bucket is initialized in full state. Every request will refill
the bucket if needed and check if the new token amount is enough
to make the request. On success the request tokens are removed from
the bucket and the function returns {:allow, requests, bucket_ref}
where requests is the number of possible additional requests based
on the remaining tokens in the bucket. Otherwise, the bucket is left
untouched and the function returns {:deny, timeout, bucket_ref}
where timeout is estimated period in ms after which the request may
be allowed, according to the bucket state and the refill rate.
bucket_ref is a reference to the bucket atomic.
Arguments:
bucketbucket id, unique within its tablewindowdefines window in secondswindow_requestsnumber of allowed requests in the window, according to the target rate. Together with window defines refill rate of the bucket.burst_requestsnumber of burst requests. Defines bucket capacity. Bursts ignore target request rate, and thus may significantly alter effective rate.
Supported options:
persistentif true, the bucket reference is also cached in:persistent_term. Default is false.refbucket atomic reference. If provided, the call will try to use it instead of refetching.tableETS table name atom. Default is AtomicBucket.
Starts the process that manages ETS table for bucket data and periodically deletes idle buckets.
The function does only basic validation of the cleanup parameters. Developers must ensure that buckets idling for more than ~24 days are deleted: longer periods are not supported by the wrapping timer used by the library.
In addition to standard GenServer options, accepts the following:
:cleanup_intervalinterval in ms defining how often the server will try to delete idle buckets. Default is 1 hour.:max_idle_periodmax period in ms since last allowed request before the bucket is deleted. Default is 24 hours.tableETS table name atom. Default is AtomicBucket.