From 22e9135e0ce6d67fdfc3308171c3db321bf154f8 Mon Sep 17 00:00:00 2001 From: Ben Busby Date: Fri, 18 Mar 2022 13:51:37 -0600 Subject: [PATCH] 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 --- lib/farside.ex | 19 +++++++++++-------- lib/farside/router.ex | 9 ++++++++- lib/farside/throttle.ex | 3 +-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/farside.ex b/lib/farside.ex index ea574fa..16dc074 100644 --- a/lib/farside.ex +++ b/lib/farside.ex @@ -26,6 +26,15 @@ defmodule Farside do end) end + def last_instance(service) do + {:ok, previous} = + Redix.command( + :redix, + ["GET", "#{service}#{@previous_suffix}"] + ) + previous + end + def pick_instance(service) do {:ok, instances} = 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 instance = if Enum.count(instances) > 0 do @@ -48,14 +57,8 @@ defmodule Farside do else # ...otherwise pick a random one from the list, ensuring # that the same instance is never picked twice in a row. - {:ok, previous} = - Redix.command( - :redix, - ["GET", "#{service}#{@previous_suffix}"] - ) - instance = - Enum.filter(instances, &(&1 != previous)) + Enum.filter(instances, &(&1 != last_instance(service))) |> Enum.random() Redix.command( diff --git a/lib/farside/router.ex b/lib/farside/router.ex index 2f0216c..f037ee2 100644 --- a/lib/farside/router.ex +++ b/lib/farside/router.ex @@ -40,7 +40,14 @@ defmodule Farside.Router do get "/:service/*glob" do 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 = cond do diff --git a/lib/farside/throttle.ex b/lib/farside/throttle.ex index 8bbf54c..e2561ab 100644 --- a/lib/farside/throttle.ex +++ b/lib/farside/throttle.ex @@ -14,8 +14,7 @@ defmodule Farside.Throttle do def allow_action(conn, _data, _opts), do: conn def block_action(conn, _data, _opts) do + conn = assign(conn, :throttle, 1) conn - |> send_resp(:forbidden, "Exceeded rate limit\n") - |> halt end end