2016-09-07 54 views
0

我試圖啓動監事和GenServer沒有實現:無法啓動主管:(Protocol.UndefinedError)協議可枚舉的

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 

我試着改變一些參數,仔細查看文檔,但我很難過。

+0

你'GenServer.start_link'用'interval'不能以'[間隔]'。嘗試取代它 – TheAnh

回答

3

有在代碼中幾個問題:

  1. children需要一個列表。
  2. GenServer.start_link的第二個參數應該只是interval而不是[interval]
  3. 你需要inspect()狀態,然後將它注入字符串插值,因爲它是一個元組。
  4. 有沒有: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 
+0

關於監,我覺得我嘗試了一切。但是,我沒有意識到,孩子們必須成爲一個名單。這是關鍵。謝謝! – sheldonkreger