无法启动主管:(Protocol.UndefinedError) 协议 Enumerable 未实现
Unable to start supervisor: (Protocol.UndefinedError) protocol Enumerable not implemented for
我正在尝试启动一个 Supervisor 和一个 GenServer:
defmodule SubscriptionManagerSupervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, [], [{:name, __MODULE__}])
end
# supervisor callback
def init([]) do
interval = 1000
children = worker(SubscriptionManagerServer, [interval])
supervise(children, strategy: :one_for_one)
end
end
还有我的 GenServer:
defmodule SubscriptionManagerServer do
use GenServer
import Logger
def start_link(interval) do
GenServer.start_link(__MODULE__, [interval])
end
def init(interval) do
state = :calendar.universal_time()
Logger.info "SubscriptionManagerServer init(). State: #{state} interval: #{interval}"
# This will send message to self on the interval. handle_info handles it.
:timer.send_interval(interval)
{:ok, state}
end
def handle_info(url, state) do
new_state = :calendar.universal_time()
Logger.info "SubscriptionManager handle_info(). new_state: #{new_state}"
{:noreply, new_state}
end
end
我尝试开始一切:
defmodule SubscriptionManagerApp do
use Application
import Logger
def start(_type, _args) do
Logger.info "Starting the SubscriptionManager."
SubscriptionManagerSupervisor.start_link()
end
end
但是,我收到以下错误:
** (Mix) Could not start application subscription_manager: SubscriptionManagerApp.start(:normal, []) returned an error: an exception was raised:
** c for {SubscriptionManagerServer, {SubscriptionManagerServer, :start_link, [1000]}, :permanent, 5000, :worker, [SubscriptionManagerServer]}
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:116: Enumerable.reduce/3
(elixir) lib/enum.ex:1636: Enum.reduce/3
(elixir) lib/enum.ex:1188: Enum.map/2
(elixir) lib/supervisor/spec.ex:169: Supervisor.Spec.supervise/2
(stdlib) supervisor.erl:294: :supervisor.init/1
(stdlib) gen_server.erl:328: :gen_server.init_it/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
我尝试更改一些参数并仔细查看文档,但我很困惑。
代码中存在几个问题:
children
需要是一个列表。
GenServer.start_link
的第二个参数应该只是 interval
,而不是 [interval]
.
- 在将其注入字符串插值之前,您需要
inspect()
状态,因为它是一个元组。
- 没有
:timer.send_interval/1
,只有/2
和/3
。
最终更改:
@@ -8,7 +8,7 @@ defmodule SubscriptionManagerSupervisor do
# supervisor callback
def init([]) do
interval = 1000
- children = worker(SubscriptionManagerServer, [interval])
+ children = [worker(SubscriptionManagerServer, [interval])]
supervise(children, strategy: :one_for_one)
end
end
@@ -18,20 +18,20 @@ defmodule SubscriptionManagerServer do
import Logger
def start_link(interval) do
- GenServer.start_link(__MODULE__, [interval])
+ GenServer.start_link(__MODULE__, interval)
end
def init(interval) do
state = :calendar.universal_time()
- Logger.info "SubscriptionManagerServer init(). State: #{state} interval: #{interval}"
+ Logger.info "SubscriptionManagerServer init(). State: #{inspect(state)} interval: #{interval}"
# This will send message to self on the interval. handle_info handles it.
- :timer.send_interval(interval)
+ :timer.send_interval(interval, :tick)
{:ok, state}
end
def handle_info(url, state) do
new_state = :calendar.universal_time()
- Logger.info "SubscriptionManager handle_info(). new_state: #{new_state}"
+ Logger.info "SubscriptionManager handle_info(). new_state: #{inspect(new_state)}"
{:noreply, new_state}
end
end
演示:
$ mix run --no-halt
16:08:17.771 [info] Starting the SubscriptionManager.
16:08:17.776 [info] SubscriptionManagerServer init(). State: {{2016, 9, 7}, {10, 38, 17}} interval: 1000
16:08:18.780 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 18}}
16:08:19.780 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 19}}
16:08:20.784 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 20}}
16:08:21.784 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 21}}
16:08:22.782 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 22}}
^C
我正在尝试启动一个 Supervisor 和一个 GenServer:
defmodule SubscriptionManagerSupervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, [], [{:name, __MODULE__}])
end
# supervisor callback
def init([]) do
interval = 1000
children = worker(SubscriptionManagerServer, [interval])
supervise(children, strategy: :one_for_one)
end
end
还有我的 GenServer:
defmodule SubscriptionManagerServer do
use GenServer
import Logger
def start_link(interval) do
GenServer.start_link(__MODULE__, [interval])
end
def init(interval) do
state = :calendar.universal_time()
Logger.info "SubscriptionManagerServer init(). State: #{state} interval: #{interval}"
# This will send message to self on the interval. handle_info handles it.
:timer.send_interval(interval)
{:ok, state}
end
def handle_info(url, state) do
new_state = :calendar.universal_time()
Logger.info "SubscriptionManager handle_info(). new_state: #{new_state}"
{:noreply, new_state}
end
end
我尝试开始一切:
defmodule SubscriptionManagerApp do
use Application
import Logger
def start(_type, _args) do
Logger.info "Starting the SubscriptionManager."
SubscriptionManagerSupervisor.start_link()
end
end
但是,我收到以下错误:
** (Mix) Could not start application subscription_manager: SubscriptionManagerApp.start(:normal, []) returned an error: an exception was raised:
** c for {SubscriptionManagerServer, {SubscriptionManagerServer, :start_link, [1000]}, :permanent, 5000, :worker, [SubscriptionManagerServer]}
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:116: Enumerable.reduce/3
(elixir) lib/enum.ex:1636: Enum.reduce/3
(elixir) lib/enum.ex:1188: Enum.map/2
(elixir) lib/supervisor/spec.ex:169: Supervisor.Spec.supervise/2
(stdlib) supervisor.erl:294: :supervisor.init/1
(stdlib) gen_server.erl:328: :gen_server.init_it/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
我尝试更改一些参数并仔细查看文档,但我很困惑。
代码中存在几个问题:
children
需要是一个列表。GenServer.start_link
的第二个参数应该只是interval
,而不是[interval]
.- 在将其注入字符串插值之前,您需要
inspect()
状态,因为它是一个元组。 - 没有
:timer.send_interval/1
,只有/2
和/3
。
最终更改:
@@ -8,7 +8,7 @@ defmodule SubscriptionManagerSupervisor do
# supervisor callback
def init([]) do
interval = 1000
- children = worker(SubscriptionManagerServer, [interval])
+ children = [worker(SubscriptionManagerServer, [interval])]
supervise(children, strategy: :one_for_one)
end
end
@@ -18,20 +18,20 @@ defmodule SubscriptionManagerServer do
import Logger
def start_link(interval) do
- GenServer.start_link(__MODULE__, [interval])
+ GenServer.start_link(__MODULE__, interval)
end
def init(interval) do
state = :calendar.universal_time()
- Logger.info "SubscriptionManagerServer init(). State: #{state} interval: #{interval}"
+ Logger.info "SubscriptionManagerServer init(). State: #{inspect(state)} interval: #{interval}"
# This will send message to self on the interval. handle_info handles it.
- :timer.send_interval(interval)
+ :timer.send_interval(interval, :tick)
{:ok, state}
end
def handle_info(url, state) do
new_state = :calendar.universal_time()
- Logger.info "SubscriptionManager handle_info(). new_state: #{new_state}"
+ Logger.info "SubscriptionManager handle_info(). new_state: #{inspect(new_state)}"
{:noreply, new_state}
end
end
演示:
$ mix run --no-halt
16:08:17.771 [info] Starting the SubscriptionManager.
16:08:17.776 [info] SubscriptionManagerServer init(). State: {{2016, 9, 7}, {10, 38, 17}} interval: 1000
16:08:18.780 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 18}}
16:08:19.780 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 19}}
16:08:20.784 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 20}}
16:08:21.784 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 21}}
16:08:22.782 [info] SubscriptionManager handle_info(). new_state: {{2016, 9, 7}, {10, 38, 22}}
^C