diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/pool/connections.ex | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/lib/pleroma/pool/connections.ex b/lib/pleroma/pool/connections.ex index acafe1bea..984057ab9 100644 --- a/lib/pleroma/pool/connections.ex +++ b/lib/pleroma/pool/connections.ex @@ -12,6 +12,7 @@ defmodule Pleroma.Pool.Connections do @type domain :: String.t() @type conn :: Pleroma.Gun.Conn.t() + @type seconds :: pos_integer() @type t :: %__MODULE__{ conns: %{domain() => conn()}, @@ -26,7 +27,10 @@ defmodule Pleroma.Pool.Connections do end @impl true - def init(opts), do: {:ok, %__MODULE__{conns: %{}, opts: opts}} + def init(opts) do + schedule_close_idle_conns() + {:ok, %__MODULE__{conns: %{}, opts: opts}} + end @spec checkin(String.t() | URI.t(), atom()) :: pid() | nil def checkin(url, name) @@ -154,16 +158,16 @@ defmodule Pleroma.Pool.Connections do def handle_call(:unused_conns, _from, state) do unused_conns = state.conns - |> Enum.filter(&filter_conns/1) - |> Enum.sort(&sort_conns/2) + |> Enum.filter(&idle_conn?/1) + |> Enum.sort(&least_used/2) {:reply, unused_conns, state} end - defp filter_conns({_, %{conn_state: :idle, used_by: []}}), do: true - defp filter_conns(_), do: false + defp idle_conn?({_, %{conn_state: :idle}}), do: true + defp idle_conn?(_), do: false - defp sort_conns({_, c1}, {_, c2}) do + defp least_used({_, c1}, {_, c2}) do c1.crf <= c2.crf and c1.last_reference <= c2.last_reference end @@ -265,6 +269,38 @@ defmodule Pleroma.Pool.Connections do {:noreply, state} end + @impl true + def handle_info({:close_idle_conns, max_idle_time}, state) do + closing_time = :os.system_time(:second) - max_idle_time + + idle_conns_keys = + state.conns + |> Enum.filter(&idle_more_than?(&1, closing_time)) + |> Enum.map(fn {key, %{conn: conn}} -> + Gun.close(conn) + key + end) + + schedule_close_idle_conns() + {:noreply, put_in(state.conns, Map.drop(state.conns, idle_conns_keys))} + end + + defp schedule_close_idle_conns do + max_idle_time = Config.get([:connections_pool, :max_idle_time], 10) * 60 + interval = Config.get([:connections_pool, :closing_idle_conns_interval], 10) * 60 * 1000 + Process.send_after(self(), {:close_idle_conns, max_idle_time}, interval) + end + + defp idle_more_than?( + {_, %{conn_state: :idle, last_reference: idle_since}}, + closing_time + ) + when closing_time >= idle_since do + true + end + + defp idle_more_than?(_, _), do: false + defp find_conn(conns, conn_pid) do Enum.find(conns, fn {_key, conn} -> conn.conn == conn_pid |