mirror of
https://github.com/benbusby/farside.git
synced 2025-04-30 07:30:02 +00:00
Reuse previous instance within rate-limit interval
Rather than blocking <1s back-to-back queries from the same IP, Farside will now re-use the previously selected instance. Fixes #20
This commit is contained in:
parent
20347822da
commit
22e9135e0c
3 changed files with 20 additions and 11 deletions
|
@ -26,6 +26,15 @@ defmodule Farside do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def last_instance(service) do
|
||||||
|
{:ok, previous} =
|
||||||
|
Redix.command(
|
||||||
|
:redix,
|
||||||
|
["GET", "#{service}#{@previous_suffix}"]
|
||||||
|
)
|
||||||
|
previous
|
||||||
|
end
|
||||||
|
|
||||||
def pick_instance(service) do
|
def pick_instance(service) do
|
||||||
{:ok, instances} =
|
{:ok, instances} =
|
||||||
Redix.command(
|
Redix.command(
|
||||||
|
@ -38,7 +47,7 @@ defmodule Farside do
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Either pick a random available instance,
|
# Either pick a random available instance,
|
||||||
# or fall back to the default one
|
# or fall back to the default one
|
||||||
instance =
|
instance =
|
||||||
if Enum.count(instances) > 0 do
|
if Enum.count(instances) > 0 do
|
||||||
|
@ -48,14 +57,8 @@ defmodule Farside do
|
||||||
else
|
else
|
||||||
# ...otherwise pick a random one from the list, ensuring
|
# ...otherwise pick a random one from the list, ensuring
|
||||||
# that the same instance is never picked twice in a row.
|
# that the same instance is never picked twice in a row.
|
||||||
{:ok, previous} =
|
|
||||||
Redix.command(
|
|
||||||
:redix,
|
|
||||||
["GET", "#{service}#{@previous_suffix}"]
|
|
||||||
)
|
|
||||||
|
|
||||||
instance =
|
instance =
|
||||||
Enum.filter(instances, &(&1 != previous))
|
Enum.filter(instances, &(&1 != last_instance(service)))
|
||||||
|> Enum.random()
|
|> Enum.random()
|
||||||
|
|
||||||
Redix.command(
|
Redix.command(
|
||||||
|
|
|
@ -40,7 +40,14 @@ defmodule Farside.Router do
|
||||||
|
|
||||||
get "/:service/*glob" do
|
get "/:service/*glob" do
|
||||||
path = Enum.join(glob, "/")
|
path = Enum.join(glob, "/")
|
||||||
instance = Farside.pick_instance(service)
|
instance = cond do
|
||||||
|
conn.assigns[:throttle] != nil ->
|
||||||
|
Farside.last_instance(service)
|
||||||
|
true ->
|
||||||
|
Farside.pick_instance(service)
|
||||||
|
end
|
||||||
|
IO.inspect(get_req_header(conn, "throttle"))
|
||||||
|
IO.inspect(instance)
|
||||||
|
|
||||||
params =
|
params =
|
||||||
cond do
|
cond do
|
||||||
|
|
|
@ -14,8 +14,7 @@ defmodule Farside.Throttle do
|
||||||
def allow_action(conn, _data, _opts), do: conn
|
def allow_action(conn, _data, _opts), do: conn
|
||||||
|
|
||||||
def block_action(conn, _data, _opts) do
|
def block_action(conn, _data, _opts) do
|
||||||
|
conn = assign(conn, :throttle, 1)
|
||||||
conn
|
conn
|
||||||
|> send_resp(:forbidden, "Exceeded rate limit\n")
|
|
||||||
|> halt
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue