Elixir 无法启动监控程序:(Protocol.UndefinedError)未为实现协议枚举

Elixir 无法启动监控程序:(Protocol.UndefinedError)未为实现协议枚举,elixir,otp,erlang-supervisor,gen-server,Elixir,Otp,Erlang Supervisor,Gen Server,我正在尝试启动一个主管和一个GenServer: defmodule SubscriptionManagerSupervisor do use Supervisor def start_link do Supervisor.start_link(__MODULE__, [], [{:name, __MODULE__}]) end # supervisor callback def init([]) do interval = 1000 childr

我正在尝试启动一个主管和一个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
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
还有我的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
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

我试着改变了一些论点,仔细阅读了文档,但我被难住了

代码中有几个问题:

  • 子项
    需要是一个列表
  • GenServer.start\u link
    的第二个参数应该是
    interval
    ,而不是
    [interval]
  • 在将其作为元组注入字符串插值之前,需要
    inspect()
    状态
  • 没有
    :计时器。发送间隔/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
    
    演示:


    代码中有几个问题:

  • 子项
    需要是一个列表
  • GenServer.start\u link
    的第二个参数应该是
    interval
    ,而不是
    [interval]
  • 在将其作为元组注入字符串插值之前,需要
    inspect()
    状态
  • 没有
    :计时器。发送间隔/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
    
    演示:


    你的
    GenServer.start\u link
    使用
    interval
    而不是
    [interval]
    。试着替换你的
    GenServer.start\u link
    使用
    interval
    而不是
    [interval]
    。试着替换它根据主管,我觉得我什么都试过了。然而,我没有意识到孩子必须是一个列表。这是关键。谢谢关于主管,我觉得我什么都试过了。然而,我没有意识到孩子必须是一个列表。这是关键。谢谢