# HammerBackendEredisCluster
A clustered-Redis backend for the [Hammer](https://github.com/ExHammer/hammer)
rate-limiter (Hammer v7+), built on
[eredis_cluster](https://github.com/Nordix/eredis_cluster).
Keys embed a `{hash tag}` so every window of a key maps to the same cluster
slot — the reason to pick this over the single-node official
[hammer-backend-redis](https://github.com/ExHammer/hammer-backend-redis).
## Installation
Add `hammer_backend_eredis_cluster` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:hammer_backend_eredis_cluster, "~> 2.0"},
{:hammer, "~> 7.0"}
]
end
```
> 2.0.0 is also mirrored in the `loopsocial` org repo (`hexpm:loopsocial`),
> where it was first published while public package ownership was being
> restored — consumers pinned there can stay or drop the `organization:`
> option at their leisure.
Using Hammer 6? Stay on `{:hammer_backend_eredis_cluster, "~> 1.0"}` — 2.0 is
the Hammer 7 port and drops the v6 `Hammer.Backend` behaviour (see the
CHANGELOG).
## Usage
Define a rate limiter and start it (typically under your supervision tree):
```elixir
defmodule MyApp.RateLimit do
use Hammer, backend: Hammer.EredisCluster
end
# The cluster connection is managed elsewhere
# (e.g. `config :eredis_cluster, init_nodes: [...]`):
MyApp.RateLimit.start_link([])
# Or let the limiter establish the connection:
MyApp.RateLimit.start_link(
servers: [{"127.0.0.1", 7001}, {"127.0.0.1", 7002}],
options: [username: "myuser", password: "mypassword"]
)
# Allow 10 requests per minute:
case MyApp.RateLimit.hit("user_123", :timer.minutes(1), 10) do
{:allow, _count} -> :ok
{:deny, retry_ms} -> {:error, {:rate_limited, retry_ms}}
end
```
`use Hammer, backend: Hammer.EredisCluster` accepts `:cluster` (eredis_cluster
name, default `:eredis_cluster_default`), `:prefix` (Redis key prefix, default:
the module name) and `:algorithm` (only `:fix_window`). See the
`Hammer.EredisCluster` module docs.
## Documentation
On hexdocs: [https://hexdocs.pm/hammer_backend_eredis_cluster/](https://hexdocs.pm/hammer_backend_eredis_cluster/)
## Run tests locally
Tests need a real Redis cluster. Either `docker-compose up -d` (see
docker-compose.yml) and run tests with
`REDIS_CLUSTER_NODES=redis-master-1:6379,redis-master-2:6379,redis-master-3:6379`,
or start three local cluster-mode nodes on ports 7001-7003 (the default
`REDIS_CLUSTER_NODES`):
```bash
for p in 7001 7002 7003; do
redis-server --port $p --cluster-enabled yes --cluster-config-file /tmp/rc/node-$p.conf \
--dir /tmp/rc --daemonize yes --save "" --appendonly no
done
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 \
--cluster-replicas 0 --cluster-yes
mix test
```
## Getting Help
If you're having trouble, open an issue on this repo.