diff options
-rw-r--r-- | lib/pleroma/application.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/application/agent.ex | 45 | ||||
-rw-r--r-- | lib/pleroma/application/dynamic_supervisor.ex | 45 |
3 files changed, 53 insertions, 39 deletions
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 27ed91554..b1ad67ee8 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -85,7 +85,7 @@ defmodule Pleroma.Application do children = [ Pleroma.Repo, Pleroma.Application.DynamicSupervisor, - {Registry, keys: :duplicate, name: Pleroma.Application.DynamicSupervisor.registry()} + Pleroma.Application.Agent ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html diff --git a/lib/pleroma/application/agent.ex b/lib/pleroma/application/agent.ex new file mode 100644 index 000000000..cf37ef952 --- /dev/null +++ b/lib/pleroma/application/agent.ex @@ -0,0 +1,45 @@ +# # Pleroma: A lightweight social networking server +# # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# # SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Application.Agent do + use Agent + + def start_link(_) do + Agent.start_link(fn -> %{reboot_paths: [], pids: %{}} end, name: __MODULE__) + end + + @spec pid(any()) :: pid() + def pid(key) do + Agent.get(__MODULE__, fn state -> state[:pids][key] end) + end + + @spec put_pid(any(), pid()) :: :ok + def put_pid(key, pid) do + Agent.update(__MODULE__, fn state -> put_in(state, [:pids, key], pid) end) + end + + @spec delete_pid(any()) :: :ok + def delete_pid(key) do + Agent.update(__MODULE__, fn state -> put_in(state[:pids], Map.delete(state[:pids], key)) end) + end + + @spec put_paths([any()]) :: :ok + def put_paths(paths) do + Agent.update(__MODULE__, fn state -> + put_in(state[:reboot_paths], Enum.uniq(state[:reboot_paths] ++ paths)) + end) + end + + @spec get_and_reset_paths() :: [any()] + def get_and_reset_paths do + Agent.get_and_update(__MODULE__, fn state -> + {state[:reboot_paths], put_in(state[:reboot_paths], [])} + end) + end + + @spec paths() :: [any()] + def paths do + Agent.get(__MODULE__, fn state -> state[:reboot_paths] end) + end +end diff --git a/lib/pleroma/application/dynamic_supervisor.ex b/lib/pleroma/application/dynamic_supervisor.ex index d1c683a5b..54af19e63 100644 --- a/lib/pleroma/application/dynamic_supervisor.ex +++ b/lib/pleroma/application/dynamic_supervisor.ex @@ -7,8 +7,6 @@ defmodule Pleroma.Application.DynamicSupervisor do require Logger - @registry Pleroma.Application.DynamicSupervisor.Registry - @type child() :: Supervisor.child_spec() | {module(), term()} @@ -19,16 +17,11 @@ defmodule Pleroma.Application.DynamicSupervisor do @impl true def init(_), do: DynamicSupervisor.init(strategy: :one_for_one) - @spec registry() :: module() - def registry, do: @registry - @spec start_child(child()) :: DynamicSupervisor.on_start_child() def start_child(child), do: DynamicSupervisor.start_child(__MODULE__, child) @spec start_children(Pleroma.Application.env()) :: :ok def start_children(env) do - start_agent() - [ Pleroma.Plugs.RateLimiter.Supervisor, Oban, @@ -42,17 +35,6 @@ defmodule Pleroma.Application.DynamicSupervisor do |> Enum.each(&start_dynamic_child/1) end - defp start_agent do - {:ok, pid} = DynamicSupervisor.start_child(__MODULE__, {Agent, fn -> [] end}) - - Registry.register(@registry, "agent", pid) - end - - defp find_in_registry(key) do - [{_, pid}] = Registry.lookup(@registry, key) - pid - end - defp add_http_children(children, :test) do [Pleroma.Application.HackneySupervisor, Pleroma.Application.GunSupervisor | children] end @@ -77,12 +59,12 @@ defmodule Pleroma.Application.DynamicSupervisor do with {:ok, pid} <- dynamic_child(child), mappings <- find_mappings(child) do Enum.each(mappings, fn {key, _} -> - Registry.register(@registry, key, pid) + Pleroma.Application.Agent.put_pid(key, pid) end) else :ignore -> # consider this behavior is normal - Logger.warn("#{inspect(child)} is ignored.") + Logger.info("#{inspect(child)} is ignored.") error -> Logger.warn(inspect(error)) @@ -158,32 +140,19 @@ defmodule Pleroma.Application.DynamicSupervisor do defp save_paths([]), do: :ok - defp save_paths(paths) do - "agent" - |> find_in_registry() - |> Agent.update(&Enum.uniq(&1 ++ paths)) - end + defp save_paths(paths), do: Pleroma.Application.Agent.put_paths(paths) @spec need_reboot?() :: boolean() - def need_reboot? do - paths = - "agent" - |> find_in_registry() - |> Agent.get(& &1) - - paths != [] - end + def need_reboot?, do: Pleroma.Application.Agent.paths() != [] @spec restart_children() :: :ok def restart_children do - "agent" - |> find_in_registry() - |> Agent.get_and_update(&{&1, []}) + Pleroma.Application.Agent.get_and_reset_paths() |> Enum.each(&restart_child/1) end defp restart_child(path) do - pid = find_in_registry(path) + pid = Pleroma.Application.Agent.pid(path) # main module can have multiple keys # first we search for main module @@ -192,7 +161,7 @@ defmodule Pleroma.Application.DynamicSupervisor do # then we search for mappings, which depends on this main module mappings <- find_mappings(module) do Enum.each(mappings, fn {key, _} -> - Registry.unregister(@registry, key) + Pleroma.Application.Agent.delete_pid(key) end) start_dynamic_child(module) |