Created
April 26, 2022 04:46
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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