1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Gun.ConnectionPool.Reclaimer do
6 use GenServer, restart: :temporary
8 defp registry, do: Pleroma.Gun.ConnectionPool
12 case :gen_server.start(__MODULE__, [], name: {:via, Registry, {registry(), "reclaimer"}}) do
16 {:error, {:already_registered, pid}} ->
20 {pid, Process.monitor(pid)}
25 {:ok, nil, {:continue, :reclaim}}
29 def handle_continue(:reclaim, _) do
30 max_connections = Pleroma.Config.get([:connections_pool, :max_connections])
33 [:connections_pool, :reclaim_multiplier]
34 |> Pleroma.Config.get()
35 |> Kernel.*(max_connections)
39 :telemetry.execute([:pleroma, :connection_pool, :reclaim, :start], %{}, %{
40 max_connections: max_connections,
41 reclaim_max: reclaim_max
45 # fn {_, {worker_pid, {_, used_by, crf, last_reference}}} when used_by == [] ->
46 # {worker_pid, crf, last_reference} end)
51 {{:_, :"$1", {:_, :"$2", :"$3", :"$4"}}, [{:==, :"$2", []}], [{{:"$1", :"$3", :"$4"}}]}
58 [:pleroma, :connection_pool, :reclaim, :stop],
59 %{reclaimed_count: 0},
61 max_connections: max_connections
65 {:stop, :no_unused_conns, nil}
70 |> Enum.sort(fn {_pid1, crf1, last_reference1}, {_pid2, crf2, last_reference2} ->
71 crf1 <= crf2 and last_reference1 <= last_reference2
73 |> Enum.take(reclaim_max)
76 |> Enum.each(fn {pid, _, _} ->
77 DynamicSupervisor.terminate_child(Pleroma.Gun.ConnectionPool.WorkerSupervisor, pid)
81 [:pleroma, :connection_pool, :reclaim, :stop],
82 %{reclaimed_count: Enum.count(reclaimed)},
83 %{max_connections: max_connections}