defmodule WalEx.Supervisor do
use Supervisor
alias WalEx.Configs, as: WalExConfigs
alias WalEx.DatabaseReplicationSupervisor
alias WalEx.Events
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]}
}
end
def start_link(opts) do
validate_opts(opts)
app_name = Keyword.get(opts, :name)
{:ok, _pid} = WalEx.Registry.start_registry()
name = WalEx.Registry.set_name(:set_supervisor, __MODULE__, app_name)
Supervisor.start_link(__MODULE__, configs: opts, name: name)
end
@impl true
def init(opts) do
opts
|> set_children()
|> Supervisor.init(strategy: :one_for_one)
end
defp validate_opts(opts) do
db_configs = [:hostname, :username, :password, :port, :database]
other_configs = [:subscriptions, :publication, :modules, :name]
missing_other_configs = Enum.filter(other_configs, &(not Keyword.has_key?(opts, &1)))
missing_db_configs =
case Keyword.get(opts, :url) do
nil -> Enum.filter(db_configs, &(not Keyword.has_key?(opts, &1)))
_has_url -> []
end
missing_configs = missing_db_configs ++ missing_other_configs
if not Enum.empty?(missing_configs) do
raise "Following configs are missing: #{inspect(missing_configs)}"
end
end
defp set_children(opts) do
configs = Keyword.get(opts, :configs)
app_name = Keyword.get(configs, :name)
walex_configs = [{WalExConfigs, configs: configs}]
walex_db_replication_supervisor = [{DatabaseReplicationSupervisor, app_name: app_name}]
walex_event = if is_nil(Process.whereis(Events)), do: [{Events, []}], else: []
walex_configs ++ walex_db_replication_supervisor ++ walex_event
end
end