Page MenuHomePhorge

No OneTemporary

Size
7 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/pleroma/application/dynamic_supervisor.ex b/lib/pleroma/application/dynamic_supervisor.ex
index 68b29e3f5..d1c683a5b 100644
--- a/lib/pleroma/application/dynamic_supervisor.ex
+++ b/lib/pleroma/application/dynamic_supervisor.ex
@@ -1,176 +1,222 @@
# # Pleroma: A lightweight social networking server
# # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Application.DynamicSupervisor do
use DynamicSupervisor
+ require Logger
+
@registry Pleroma.Application.DynamicSupervisor.Registry
@type child() ::
Supervisor.child_spec()
| {module(), term()}
| module()
def start_link(_), do: DynamicSupervisor.start_link(__MODULE__, :no_arg, name: __MODULE__)
@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,
Pleroma.Web.Endpoint,
Pleroma.Gopher.Server,
Pleroma.Web.ChatChannel.ChatChannelState,
Pleroma.Web.FedSockets.Supervisor
]
|> add_http_children(env)
|> add_streamer(env)
|> 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_agent do
- [{_, pid}] = Registry.lookup(@registry, "agent")
+ 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
defp add_http_children(children, _) do
adapter = Application.get_env(:tesla, :adapter)
child =
if adapter == Tesla.Adapter.Gun do
Pleroma.Application.GunSupervisor
else
- Pleroma.Application.HackneyPoolSupervisor
+ Pleroma.Application.HackneySupervisor
end
[child | children]
end
defp add_streamer(children, env) when env in [:test, :benchmark], do: children
defp add_streamer(children, _), do: [Pleroma.Web.StreamerRegistry | children]
defp start_dynamic_child(child) do
- with {:ok, pid} <- DynamicSupervisor.start_child(__MODULE__, spec(child)) do
- config_path_mappings()
- |> Enum.filter(fn {_key, module} -> child == module end)
- |> Enum.each(fn {key, _} ->
+ with {:ok, pid} <- dynamic_child(child),
+ mappings <- find_mappings(child) do
+ Enum.each(mappings, fn {key, _} ->
Registry.register(@registry, key, pid)
end)
+ else
+ :ignore ->
+ # consider this behavior is normal
+ Logger.warn("#{inspect(child)} is ignored.")
+
+ error ->
+ Logger.warn(inspect(error))
+ end
+ end
+
+ defp dynamic_child(child) do
+ with {:error, _} = error <- DynamicSupervisor.start_child(__MODULE__, spec(child)) do
+ error
end
end
defp spec(Oban), do: {Oban, Pleroma.Config.get(Oban)}
defp spec(Pleroma.Web.StreamerRegistry) do
{Registry,
[
name: Pleroma.Web.Streamer.registry(),
keys: :duplicate,
partitions: System.schedulers_online()
]}
end
defp spec(child), do: child
defp config_path_mappings do
adapter_module =
if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Gun do
Pleroma.Application.GunSupervisor
else
- Pleroma.Application.HackneyPoolSupervisor
+ Pleroma.Application.HackneySupervisor
end
[
{{:pleroma, :chat}, Pleroma.Web.ChatChannel.ChatChannelState},
{{:pleroma, Oban}, Oban},
{{:pleroma, :rate_limit}, Pleroma.Plugs.RateLimiter.Supervisor},
{{:pleroma, :streamer}, Pleroma.Web.Streamer.registry()},
{{:pleroma, :pools}, Pleroma.Application.GunSupervisor},
{{:pleroma, :connections_pool}, Pleroma.Application.GunSupervisor},
- {{:pleroma, :hackney_pools}, Pleroma.Application.HackneyPoolSupervisor},
+ {{:pleroma, :hackney_pools}, Pleroma.Application.HackneySupervisor},
{{:pleroma, Pleroma.Captcha, [:seconds_valid]}, Pleroma.Web.Endpoint},
{{:pleroma, Pleroma.Upload, [:proxy_remote]}, adapter_module},
{{:pleroma, :instance, [:upload_limit]}, Pleroma.Web.Endpoint},
{{:pleroma, :gopher, [:enabled]}, Pleroma.Gopher.Server},
{{:pleroma, :fed_sockets, [:enabled]}, Pleroma.Web.Endpoint}
]
end
@spec save_need_reboot_paths([Pleroma.ConfigDB.t()]) :: :ok
def save_need_reboot_paths([]), do: :ok
def save_need_reboot_paths(configs) do
configs
|> Enum.map(&find_path(&1.group, &1.key, &1.value))
|> Enum.filter(& &1)
|> save_paths()
end
defp find_path(group, key, value) do
with {path, _} <-
Enum.find(config_path_mappings(), fn
{{g, k}, _} ->
g == group and k == key
{{g, k, subkeys}, _} ->
Keyword.keyword?(value) and g == group and k == key and
Enum.any?(Keyword.keys(value), &(&1 in subkeys))
end) do
path
end
end
defp save_paths([]), do: :ok
- defp save_paths(paths), do: Agent.update(find_agent(), &Enum.uniq(&1 ++ paths))
+ defp save_paths(paths) do
+ "agent"
+ |> find_in_registry()
+ |> Agent.update(&Enum.uniq(&1 ++ paths))
+ end
@spec need_reboot?() :: boolean()
- def need_reboot?, do: Agent.get(find_agent(), & &1) != []
+ def need_reboot? do
+ paths =
+ "agent"
+ |> find_in_registry()
+ |> Agent.get(& &1)
+
+ paths != []
+ end
@spec restart_children() :: :ok
def restart_children do
- find_agent()
+ "agent"
+ |> find_in_registry()
|> Agent.get_and_update(&{&1, []})
|> Enum.each(&restart_child/1)
end
defp restart_child(path) do
- [{_, pid}] = Registry.lookup(@registry, path)
+ pid = find_in_registry(path)
# main module can have multiple keys
# first we search for main module
- with {_, main_module} <- Enum.find(config_path_mappings(), fn {key, _} -> key == path end) do
- DynamicSupervisor.terminate_child(__MODULE__, pid)
- # then we search for keys, which depends on this main module
- config_path_mappings()
- |> Enum.filter(fn {_, module} -> main_module == module end)
- |> Enum.each(fn {key, _} ->
+ with {_, module} <- find_mapping(path),
+ :ok <- terminate(pid),
+ # 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)
end)
- start_dynamic_child(main_module)
+ start_dynamic_child(module)
+ else
+ error ->
+ Logger.warn(inspect(error))
+ end
+ end
+
+ defp find_mapping(path) do
+ with nil <- Enum.find(config_path_mappings(), fn {key, _} -> key == path end) do
+ {:error, :mapping_not_found}
+ end
+ end
+
+ defp find_mappings(module) do
+ with [] <- Enum.filter(config_path_mappings(), fn {_, m} -> m == module end) do
+ {:error, :empty_mappings}
+ end
+ end
+
+ defp terminate(pid) do
+ with {:error, :not_found} = error <- DynamicSupervisor.terminate_child(__MODULE__, pid) do
+ error
end
end
end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Oct 11, 1:16 AM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1785522
Default Alt Text
(7 KB)

Event Timeline