I've implemented a simple Application
-> DynamicSupervisor
system where the Application
creates a single DynamicSupervisor
on startup and then sends a message to it to start some work. The problem is that none of the messages (through GenServer's cast
, Kernel's send
) actually get caught. Trying to GenServer.call()
throws the following error
no function clause matching in DynamicSupervisor.handle_call/3
which is odd since I have implemented it (to that spec). I'm sure that the DynamicSupervisor
module gets started and doesn't quit on startup.
Application module code:
defmodule Simulacra.Application do
use Application
def start(_type, _args) do
children = [
Simulacra.MainSupervisor
]
opts = [strategy: :one_for_one, name: Simulacra.Supervisor]
{:ok, pid} = Supervisor.start_link(children, opts)
start_supervisors(Supervisor.which_children(pid))
{:ok, pid}
end
defp start_supervisors([h|_t] = list) when is_list(list) do
{_, pid, _, _} = h
start_supervisors(pid)
end
defp start_supervisors([]) do
#noop
IO.puts "Something"
end
defp start_supervisors(pid) do
GenServer.cast(pid, :start)
send(pid, :ping)
GenServer.call(pid, :ping) <-- Throws an error
end
end
Supervisor code:
defmodule Simulacra.MainSupervisor do
@moduledoc false
use DynamicSupervisor
def start_link([]) do
DynamicSupervisor.start_link(__MODULE__, [], name: __MODULE__)
end
def init(_noop) do
DynamicSupervisor.init(strategy: :one_for_one)
end
def handle_info(:ping, state) do
IO.puts "sth"
end
def handle_cast(:start, state) do
# do_something
{:noreply, state}
end
def handle_call(:ping, _from, _x) do
{:reply, "bing", "bong"}
end
DynamicSupervisor
is a custom implementation of GenServer
behaviour.
The only overridable function it has is child_spec/1
.
Your casts
are although effectively ignored. When you cast a message, or send an info, VM simply ignores it when the process can not process it (or even if it does not exist.) call/3
is synchronous, so the sender expects a reply back, that is why you see it raises.
Try GenServer.cast pid, :foo
, you’ll receive :ok
back, because these messages are not promised to be delivered.