Elixir simple_one_for_one 主管的 start_child 以未定义的 handle_call/3 终止
Elixir simple_one_for_one supervisor's start_child terminates with undefined handle_call/3
我正在尝试使用 gproc 创建一个主管来进行进程注册。以下代码定义主管:
defmodule QueueSupervisor do
use Supervisor
def start_link do
GenServer.start_link(__MODULE__, [], name: :model_queue)
end
def create_queue(name) do
Supervisor.start_child(:model_queue, [name])
end
def init([]) do
children = [
worker(ModelQueueWriter, [])
]
supervise(children, strategy: :simple_one_for_one)
end
def terminate(reason,_state) do
Logger.info "terminating: #{inspect self}: #{inspect reason}"
:ok
end
end
主管开始很有魅力。但是,当调用 create_queue(:some_name)
时,出现未定义函数错误:
function QueueSupervisor.handle_call({:start_child, [:some_name]}, {#PID<0.2278.0>, #Reference<0.0.3.3361>}, {{:simple_one_for_one, 3, 5}, [{ModelQueueWriter, {ModelQueueWriter, :start_link, []}, :permanent, 5000, :worker, [ModelQueueWriter]}]}
ModelQueueWriter
是一个简单的genserver,使用gproc进行命名:
defmodule ModelQueueWriter do
use GenServer
def start_link(queue_name) do
GenServer.start_link(__MODULE__, [], name: via_tuple(queue_name))
end
defp via_tuple(queue_name) do
{:via, :gproc, {:n, :l, {:model_queue, queue_name}}}
end
def init(_), do: %{:ok, []}
end
我正在使用 elixir 1.4 并遵循 Supervisor 的文档,加上这个 example。
我错过了什么?
根据请求提供完整的错误消息:
** (exit) exited in: GenServer.call(:model_queue, {:start_child, [:some_name]}, :infinity)
** (EXIT) an exception was raised:
** (UndefinedFunctionError) function QueueSupervisor.handle_call/3 is undefined or private
(ecohesion_web) QueueSupervisor.handle_call({:start_child, [:model_queue]}, {#PID<0.2278.0>, #Reference<0.0.1.8826>}, {{:simple_one_for_one, 3, 5}, [{ModelQueueWriter, {ModelQueueWriter, :start_link, []}, :permanent, 5000, :worker, [ModelQueueWriter]}]})
(stdlib) gen_server.erl:629: :gen_server.try_handle_call/4
(stdlib) gen_server.erl:661: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
11:01:17.094 [error] GenServer :model_queue terminating
** (UndefinedFunctionError) function QueueSupervisor.handle_call/3 is undefined or private
(ecohesion_web) QueueSupervisor.handle_call({:start_child, [:model_queue]}, {#PID<0.2278.0>, #Reference<0.0.1.8826>}, {{:simple_one_for_one, 3, 5}, [{ModelQueueWriter, {ModelQueueWriter, :start_link, []}, :permanent, 5000, :worker, [ModelQueueWriter]}]})
(stdlib) gen_server.erl:629: :gen_server.try_handle_call/4
(stdlib) gen_server.erl:661: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Last message: {:start_child, [mode_queue]}
State: {{:simple_one_for_one, 3, 5}, [{ModelQueueWriter, {ModelQueueWriter, :start_link, []}, :permanent, 5000, :worker, [ModelQueueWriter]}]}
(elixir) lib/gen_server.ex:737: GenServer.call/3
(ecohesion_web) lib/ecohesion_web/archive_writer/queue_supervisor.ex:28: QueueSupervisor.create_queue/1
您将在 QueueSupervisor.start_link/0
中开始 GenServer
而不是 Supervisor
。这应该有效:
defmodule QueueSupervisor do
def start_link do
Supervisor.start_link(__MODULE__, [], name: :model_queue)
end
end
Why does that even start the supervisor properly?
它启动了一个GenServer
;只是您使用的参数与 Supervisor.start_link/3
和 GenServer.start_link/3
.
兼容
我正在尝试使用 gproc 创建一个主管来进行进程注册。以下代码定义主管:
defmodule QueueSupervisor do
use Supervisor
def start_link do
GenServer.start_link(__MODULE__, [], name: :model_queue)
end
def create_queue(name) do
Supervisor.start_child(:model_queue, [name])
end
def init([]) do
children = [
worker(ModelQueueWriter, [])
]
supervise(children, strategy: :simple_one_for_one)
end
def terminate(reason,_state) do
Logger.info "terminating: #{inspect self}: #{inspect reason}"
:ok
end
end
主管开始很有魅力。但是,当调用 create_queue(:some_name)
时,出现未定义函数错误:
function QueueSupervisor.handle_call({:start_child, [:some_name]}, {#PID<0.2278.0>, #Reference<0.0.3.3361>}, {{:simple_one_for_one, 3, 5}, [{ModelQueueWriter, {ModelQueueWriter, :start_link, []}, :permanent, 5000, :worker, [ModelQueueWriter]}]}
ModelQueueWriter
是一个简单的genserver,使用gproc进行命名:
defmodule ModelQueueWriter do
use GenServer
def start_link(queue_name) do
GenServer.start_link(__MODULE__, [], name: via_tuple(queue_name))
end
defp via_tuple(queue_name) do
{:via, :gproc, {:n, :l, {:model_queue, queue_name}}}
end
def init(_), do: %{:ok, []}
end
我正在使用 elixir 1.4 并遵循 Supervisor 的文档,加上这个 example。
我错过了什么?
根据请求提供完整的错误消息:
** (exit) exited in: GenServer.call(:model_queue, {:start_child, [:some_name]}, :infinity)
** (EXIT) an exception was raised:
** (UndefinedFunctionError) function QueueSupervisor.handle_call/3 is undefined or private
(ecohesion_web) QueueSupervisor.handle_call({:start_child, [:model_queue]}, {#PID<0.2278.0>, #Reference<0.0.1.8826>}, {{:simple_one_for_one, 3, 5}, [{ModelQueueWriter, {ModelQueueWriter, :start_link, []}, :permanent, 5000, :worker, [ModelQueueWriter]}]})
(stdlib) gen_server.erl:629: :gen_server.try_handle_call/4
(stdlib) gen_server.erl:661: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
11:01:17.094 [error] GenServer :model_queue terminating
** (UndefinedFunctionError) function QueueSupervisor.handle_call/3 is undefined or private
(ecohesion_web) QueueSupervisor.handle_call({:start_child, [:model_queue]}, {#PID<0.2278.0>, #Reference<0.0.1.8826>}, {{:simple_one_for_one, 3, 5}, [{ModelQueueWriter, {ModelQueueWriter, :start_link, []}, :permanent, 5000, :worker, [ModelQueueWriter]}]})
(stdlib) gen_server.erl:629: :gen_server.try_handle_call/4
(stdlib) gen_server.erl:661: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Last message: {:start_child, [mode_queue]}
State: {{:simple_one_for_one, 3, 5}, [{ModelQueueWriter, {ModelQueueWriter, :start_link, []}, :permanent, 5000, :worker, [ModelQueueWriter]}]}
(elixir) lib/gen_server.ex:737: GenServer.call/3
(ecohesion_web) lib/ecohesion_web/archive_writer/queue_supervisor.ex:28: QueueSupervisor.create_queue/1
您将在 QueueSupervisor.start_link/0
中开始 GenServer
而不是 Supervisor
。这应该有效:
defmodule QueueSupervisor do
def start_link do
Supervisor.start_link(__MODULE__, [], name: :model_queue)
end
end
Why does that even start the supervisor properly?
它启动了一个GenServer
;只是您使用的参数与 Supervisor.start_link/3
和 GenServer.start_link/3
.