The doc of Supervisor says any exit reason other than :normal, :shutdown or {:shutdown, term} will be logged.
But I didn’t see any error log with these code:
defmodule MyWorker do
def start_link(_) do
pid = spawn_link(fn ->
IO.puts "Worker say hello"
:timer.sleep(1000)
exit(:goodbye)
end)
{:ok, pid}
end
end
defmodule MySup do
use Supervisor
def start_link(_) do
Supervisor.start_link(__MODULE__, :ok)
end
def init(_) do
[
%{start: {MyWorker, :start_link, [:ok]}, id: :my_worker}
]
|> Supervisor.init(strategy: :one_for_one)
end
end
run with MySup.start_link(:ok), it just restart the worker 3 times without any error log. Did I missing something?
After change the children worker into a GenServer, it logs when child terminated:
defmodule MyGenServerWorker do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, :ok)
end
def init(_) do
{:ok, nil, {:continue, :goodbye}}
end
def handle_continue(:goodbye, state) do
IO.puts "GenServer say hello"
:timer.sleep(1000)
{:stop, :goodbye, state}
end
end
The docs could probably be clearer about this but yeah Supervisor’s can only supervise OTP compliant processes. Your initial process doesn’t respond to the init message or return the appropriate response, so the supervisor process is actually just locked up.
The worker didn’t receive any message in my example.
defmodule MyWorker do
def start_link(_) do
pid = spawn_link(fn ->
IO.puts "Worker say hello"
:timer.sleep(1000)
receive do
m -> IO.inspect m
end
exit(:goodbye)
end)
{:ok, pid}
end
end
If you send the supervisor pid a message of the right shape from your pid then that’d at least get you past the init phase. However your process wouldn’t respond correctly to get_state messages and so forth. At that point you’re just reimplimenting the genserver module and should probably just use a genserver.
I think the supervisor can supervise non-OTP processes.
The proc_lib is for blocking init, which is not a requirement for supervisors, but a feature if you need it. I think the supervisor does not use system messages. But in a nutshell you are right: it is probably better to roll with GenServer.
When it comes to logging, it is also done by the behaviours, so we need to update the docs. Will do.