Skip to content

Instantly share code, notes, and snippets.

@c4710n
Created April 26, 2022 04:46
Show Gist options
  • Save c4710n/0efec2294bdb921576c8e56688c35d4b to your computer and use it in GitHub Desktop.
Save c4710n/0efec2294bdb921576c8e56688c35d4b to your computer and use it in GitHub Desktop.
Check the rate of requests, and tag the corresponding connections with oveload tag.
defmodule PlugOverloadDetector do
@moduledoc """
Check the rate of requests, and tag the corresponding connections with
`conn.assigns.overload = true` when the rate is too high.
> The related package is ex_rated.
## Usage
### Use in routers
Just use it as a plug implemented as module.
### Use in controllers
```elixir
import PlugOverloadDetector, only: [overload_detector: 2]
plug :overload_detector, when action in [:show]
```
"""
@behaviour Plug
def init(opts), do: opts
def call(conn, opts \\ []) do
case check_rate(conn, opts) do
{:ok, _count} -> conn
{:error, _limit} -> Plug.Conn.assign(conn, :overload, true)
end
end
def overload_detector(conn, opts) do
call(conn, opts)
end
defp check_rate(conn, opts) do
interval = Keyword.get(opts, :interval, 1)
max_requests = Keyword.get(opts, :max_requests, 1_000)
bucket_name = Keyword.get(opts, :bucket_name, bucket_name(conn))
ExRated.check_rate(bucket_name, :timer.seconds(interval), max_requests)
end
defp bucket_name(conn) do
Enum.join(conn.path_info, "/")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment