[](https://github.com/jechol/dist_limiter/actions)
[](https://hex.pm/packages/dist_limiter)
[](https://github.com/jechol/dist_limiter/blob/master/LICENSE.md)
# DistLimiter
Distributed rate limiter.
## Features
### Distributed
Built on top of `pg`, nodes which are interested in the same resource automatically form a process group. They record local `consume` timestamps and exchange those records with other nodes when being asked to `consume`.
### Garbage collection
Member processes automatically stop when `window` milliseconds elapsed after last `consume` on the node.
### Sliding window algorithm
`dist_limiter` implemented sliding window algorithm.
## Usage
Let's say we want to limit password challenge from IP "a.b.c.d" to at most 3 times a hour.
```elixir
iex(1)> resource = {:ip, "a.b.c.d", :challenge_password}
{:ip, "a.b.c.d", :challenge_password}
iex(2)> limit = {3600 * 1000, 3}
{3600000, 3}
iex(3)> DistLimiter.get_remaining(resource, limit)
3
iex(4)> DistLimiter.consume(resource, limit, 1)
{:ok, 2}
iex(5)> DistLimiter.consume(resource, limit, 1)
{:ok, 1}
iex(6)> DistLimiter.consume(resource, limit, 1)
{:ok, 0}
iex(7)> DistLimiter.consume(resource, limit, 1)
{:error, :overflow}
```
## Installation
Add `dist_limiter` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:dist_limiter, "~> 0.1.1"}
]
end
```