defmodule TaskBunny.Supervisor do @moduledoc """ Main supervisor for TaskBunny. It supervises Connection and WorkerSupervisor with one_for_all strategy. When Connection crashes it restarts all Worker processes through WorkerSupervisor so workers can always use a re-established connection. You don't have to call or start the Supervisor explicity. It will be automatically started by application and configure child processes based on configuration file. """ use Supervisor alias TaskBunny.{Connection, Config, Initializer, WorkerSupervisor, PublisherWorker} @doc false @spec start_link(atom, atom) :: {:ok, pid} | {:error, term} def start_link(name \\ __MODULE__, wsv_name \\ WorkerSupervisor, ps_name \\ :publisher) do Supervisor.start_link(__MODULE__, [wsv_name, ps_name], name: name) end @doc false @spec init(list()) :: {:ok, {:supervisor.sup_flags(), [Supervisor.Spec.spec()]}} | :ignore def init([wsv_name, ps_name]) do # Add Connection severs for each hosts connections = Enum.map( Config.hosts(), fn host -> worker(Connection, [host], id: make_ref()) end ) publisher = [:poolboy.child_spec(:publisher, publisher_config(ps_name))] children = case Initializer.alive?() do true -> connections ++ publisher false -> connections ++ publisher ++ [worker(Initializer, [false])] end # Define workers and child supervisors to be supervised children = case {Config.auto_start?(), Config.disable_worker?()} do {true, false} -> children ++ [supervisor(WorkerSupervisor, [wsv_name])] {true, true} -> # Only connections children _ -> [] end supervise(children, strategy: :one_for_all) end defp publisher_config(name) do [ {:name, {:local, name}}, {:worker_module, PublisherWorker}, {:size, Config.publisher_pool_size()}, {:max_overflow, Config.publisher_max_overflow()} ] end end