Supervisors
If restarts exceed max_restarts within max_seconds, the supervisor itself exits (escalation up the tree).
33.1 Starting a supervisor
defmodule MyApp.Application do
use Application
@impl true
def start(_type, _args) do
children = [
{Stack, [:initial]}, # calls Stack.start_link([:initial])
{Task.Supervisor, name: MyApp.TaskSup},
{Registry, keys: :unique, name: MyApp.Registry},
MyApp.Cache # same as {MyApp.Cache, []}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor, max_restarts: 3, max_seconds: 5]
Supervisor.start_link(children, opts)
end
end33.2 Strategies
When a child dies...
restart only that child restart all children restart that child and all children started after it
If restarts exceed max_restarts within max_seconds, the supervisor itself exits (escalation up the tree).
33.3 Child specs
use GenServer, restart: :transient customizes the generated child_spec/1.
only on abnormal exit
%{
id: MyWorker,
start: {MyWorker, :start_link, [arg]},
restart: :permanent, # :permanent | :temporary | :transient
shutdown: 5_000, # ms, or :brutal_kill, or :infinity (for supervisors)
type: :worker # :worker | :supervisor
}33.4 Module-based supervisor
defmodule MyApp.WorkerSup do
use Supervisor
def start_link(arg), do: Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
@impl true
def init(_arg) do
children = [{Worker, 1}, {Worker, 2} |> Supervisor.child_spec(id: :worker2)]
Supervisor.init(children, strategy: :one_for_one)
end
end33.5 Supervision tree design
Principles: start order matters (dependencies first), put volatile processes deeper in the tree, group things that must restart together.
MyApp.Supervisor (one_for_one)
├── MyApp.Repo
├── MyApp.PubSub
├── MyApp.Cache.Supervisor (rest_for_one)
│ ├── MyApp.Cache.Table (owns ETS)
│ └── MyApp.Cache.Janitor
├── MyApp.SessionSupervisor (DynamicSupervisor)
└── MyAppWeb.Endpoint33.6 Inspecting
Supervisor.which_children(MyApp.Supervisor)
Supervisor.count_children(MyApp.Supervisor)
Supervisor.terminate_child / restart_child / delete_child
:observer.start() # GUI view of the tree