为什么在主管和工作人员的设置中调用 start link 时会出现 ProtocolUndefined 错误?
Why am I getting a ProtocolUndefined error when I invoke start link in this setup of a Supervisor and Worker?
我在 OTP 应用程序中有以下简单的 1 级深度 supervisor/worker 设置。
如果我启动 "iex -S mix" 并执行 MyDemo.Supervisor.start_link({MyDemo.Worker, :start_link, []})我得到以下错误输出。
1)这是为什么?看来我遵循了正确的函数签名。
代码
defmodule MyDemo.Supervisor do
use Supervisor
### API
def start_link({_, _, _} = mod_func_arg) do
Supervisor.start_link(__MODULE__, mod_func_arg)
end
def init({mod, func, arg} = x) do
opts_worker = [restart: :permanent, function: func]
children = worker(mod, arg, opts_worker)
#opts = [strategy: :simple_one_for_one, max_restarts: 5, max_seconds: 5]
opts = [strategy: :one_for_one, max_restarts: 5, max_seconds: 5]
supervise(children, opts)
end
end
defmodule MyDemo.Worker do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, :ok, [])
end
def stop(pid) do
GenServer.call(pid, :stop)
end
def handle_call(:stop, _from, state) do
{:stop, :normal, :ok, state}
end
end
错误输出
** (EXIT from #PID<0.255.0>) an exception was raised:
** (Protocol.UndefinedError) protocol Enumerable not implemented for {MyDemo.Worker, {MyDemo.Worker, :start_link, []}, :permanent,
5000, :worker, [MyDemo.Worker]}
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:116: Enumerable.reduce/3
(elixir) lib/enum.ex:1776: Enum.map/2
(elixir) lib/supervisor/spec.ex:169: Supervisor.Spec.supervise/2
(stdlib) supervisor.erl:272: :supervisor.init/1
(stdlib) gen_server.erl:328: :gen_server.init_it/6
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
尝试
children = [worker(mod, arg, opts_worker)]
supervise
函数将列表作为第一个参数。
在错误信息中
(Protocol.UndefinedError) protocol Enumerable not implemented for {MyDemo.Worker, ...}
你可以看到一个二元组,它是关键字键和值的条目。但是,它没有包含在 []
中,因此输入未指定为列表。
我在 OTP 应用程序中有以下简单的 1 级深度 supervisor/worker 设置。
如果我启动 "iex -S mix" 并执行 MyDemo.Supervisor.start_link({MyDemo.Worker, :start_link, []})我得到以下错误输出。
1)这是为什么?看来我遵循了正确的函数签名。
代码
defmodule MyDemo.Supervisor do
use Supervisor
### API
def start_link({_, _, _} = mod_func_arg) do
Supervisor.start_link(__MODULE__, mod_func_arg)
end
def init({mod, func, arg} = x) do
opts_worker = [restart: :permanent, function: func]
children = worker(mod, arg, opts_worker)
#opts = [strategy: :simple_one_for_one, max_restarts: 5, max_seconds: 5]
opts = [strategy: :one_for_one, max_restarts: 5, max_seconds: 5]
supervise(children, opts)
end
end
defmodule MyDemo.Worker do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, :ok, [])
end
def stop(pid) do
GenServer.call(pid, :stop)
end
def handle_call(:stop, _from, state) do
{:stop, :normal, :ok, state}
end
end
错误输出
** (EXIT from #PID<0.255.0>) an exception was raised: ** (Protocol.UndefinedError) protocol Enumerable not implemented for {MyDemo.Worker, {MyDemo.Worker, :start_link, []}, :permanent, 5000, :worker, [MyDemo.Worker]} (elixir) lib/enum.ex:1: Enumerable.impl_for!/1 (elixir) lib/enum.ex:116: Enumerable.reduce/3 (elixir) lib/enum.ex:1776: Enum.map/2 (elixir) lib/supervisor/spec.ex:169: Supervisor.Spec.supervise/2 (stdlib) supervisor.erl:272: :supervisor.init/1 (stdlib) gen_server.erl:328: :gen_server.init_it/6 (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
尝试
children = [worker(mod, arg, opts_worker)]
supervise
函数将列表作为第一个参数。
在错误信息中
(Protocol.UndefinedError) protocol Enumerable not implemented for {MyDemo.Worker, ...}
你可以看到一个二元组,它是关键字键和值的条目。但是,它没有包含在 []
中,因此输入未指定为列表。