Hammer behaviour (hammer v7.1.0)

View Source

Hammer is a rate-limiting library for Elixir.

It provides a simple way for creating rate limiters, and comes with a built-in ETS backend.

defmodule MyApp.RateLimit do
  use Hammer, backend: :ets
end

# Start the rate limiter, in case of ETS it will create the ETS table and schedule cleanups
MyApp.RateLimit.start_link(clean_period: :timer.minutes(10))

# Check the rate limit allowing 10 requests per second
MyApp.RateLimit.hit("some-key", _scale = :timer.seconds(1), _limit = 10)

Summary

Callbacks

Optional callback for getting the counter value for a key.

Checks if a key is allowed to perform an action, and increment the counter.

Optional callback to check if a key is allowed to perform an action, and increment the counter.

Same as inc/3 with increment set to 1.

Optional callback for incrementing a counter value for a key without performing limit check.

Optional callback for setting the counter value for a key.

Functions

Use the Hammer library in a module to create a rate limiter.

Types

count()

@type count() :: pos_integer()

increment()

@type increment() :: non_neg_integer()

key()

@type key() :: term()

limit()

@type limit() :: pos_integer()

scale()

@type scale() :: pos_integer()

Callbacks

get(key, scale)

(optional)
@callback get(key(), scale()) :: count()

Optional callback for getting the counter value for a key.

Returns the current counter value.

hit(key, scale, limit)

@callback hit(key(), scale(), limit()) :: {:allow, count()} | {:deny, timeout()}

Checks if a key is allowed to perform an action, and increment the counter.

Same as hit/4 with increment set to 1.

Note on key types: While this library accepts any term as a key, some backends may have restrictions. The Redis backend requires keys to be strings or binary types, as it needs to serialize them for storage. The ETS and Atomic backends support any term type.

hit(key, scale, limit, increment)

(optional)
@callback hit(key(), scale(), limit(), increment()) ::
  {:allow, count()} | {:deny, timeout()}

Optional callback to check if a key is allowed to perform an action, and increment the counter.

Returns {:allow, count} if the action is allowed, or {:deny, timeout} if the action is denied.

This is the only required callback.

inc(key, scale)

(optional)
@callback inc(key(), scale()) :: count()

Same as inc/3 with increment set to 1.

inc(key, scale, increment)

(optional)
@callback inc(key(), scale(), increment()) :: count()

Optional callback for incrementing a counter value for a key without performing limit check.

Returns the new counter value.

set(key, scale, count)

(optional)
@callback set(key(), scale(), count()) :: count()

Optional callback for setting the counter value for a key.

Returns the new counter value.

Functions

__using__(opts)

(macro)

Use the Hammer library in a module to create a rate limiter.

defmodule MyApp.RateLimit do
  use Hammer, backend: :ets
end