Why am I getting a ProtocolUndefined error when I invoke start link in this setup of a Supervisor and Worker?

Nona Source

I have the below simple 1 level deep supervisor/worker setup in an OTP application.

If I boot up "iex -S mix" and do MyDemo.Supervisor.start_link({MyDemo.Worker, :start_link, []}) I get the below error output.

1) Why is this? It seems like I'm following the correct function signatures.

Code

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

Error output

** (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

elixirotpsupervisor

Answers

answered 10 months ago Steve Pallen #1

Try

children = [worker(mod, arg, opts_worker)]

The supervise function takes a list as its first parameter.

In the error message

 (Protocol.UndefinedError) protocol Enumerable not implemented for {MyDemo.Worker, ...}

you can see a two element tuple, which is an entry for a keyword key and value. However, its not wrapped in a [], so that is the hind that the input is was not specified as a list.

comments powered by Disqus