‘How I Start’ tutorial problem

Hi, I new to elixir and after reading a few pages of getting started docs (I’m still reading) I’ve found this tutorial by José Valim .
But, when I reach this part of the tutorial:

The last step is to add a function named shoot/1 to the Portal module that receives a color and spawns a new door as part of the supervision tree:

@doc """
Shoots a new door with the given `color`.
"""
def shoot(color) do
  Supervisor.start_child(Portal.Supervisor, [color])
end

and I try to call “shoot” function from iex, I get:

(ArgumentError) The module Portal.Door was given as a child to a supervisor
but it does not implement child_spec/1.

Then I’ve tried to implement this way (I’m not so sure that it’s correct)

    def child_spec(opts)do
        %{
            id: Portal.Door,
            start: {Portal.Door, :start_link,[opts]},
            type: :worker,
            restart: :permanent,
            shutdown: 500
        }
    end

My code compiles, but when I try to call Poortal.shoot(:orange) I get:

{:error,
{:EXIT,
{:undef,
[
{Portal.Door, :start_link, [[], :orange], []},
{:supervisor, :do_start_child_i, 3, [file: ‘supervisor.erl’, line: 379]},
{:supervisor, :handle_call, 3, [file: ‘supervisor.erl’, line: 404]},
{:gen_server, :try_handle_call, 4, [file: ‘gen_server.erl’, line: 661]},
{:gen_server, :handle_msg, 6, [file: ‘gen_server.erl’, line: 690]},
{:proc_lib, :init_p_do_apply, 3, [file: ‘proc_lib.erl’, line: 249]}
]}}}

That’s my first tutorial using elixir, so, sorry if it’s some really newbie mistake.

:wave:

Is there a start_link function in Portal.Door module, how many arguments does it accept?

The strategy simple_one_for_one is not recommended anymore… It has been deprecated

See https://hexdocs.pm/elixir/Supervisor.html

opts = [strategy: :simple_one_for_one, name: Portal.Supervisor]

It has been replaced by Dynamic Supervisor.

But for the tutorial it’s ok to use it. I’ll try following the tutorial to see if I get any errors like OP …

1 Like

The tutorial works fine for me, the only warning I got was for String.rjust/2, which is not important.

@Marcos-Costa you might want to make sure that your start callback is exactly the same as in the tutorial:

def start(_type, _args) do
  import Supervisor.Spec, warn: false # <-- we need this import for `worker/2` below

  children = [
    worker(Portal.Door, [])
  ]

  opts = [strategy: :simple_one_for_one, name: Portal.Supervisor] # <-- note :simple_one_for_one
  Supervisor.start_link(children, opts)
end
1 Like

For anyone who might be interested, please feel free to send a PR to the tutorial for Dynamic Supervisors, https://github.com/howistart/howistart-hakyll/blob/master/posts/elixir/1/index.md

I always check with the original author, so in this case it’ll have to go through @josevalim, before merging, but great to get updates like this contributed from the community so that the tutorials keep up with changes and improvements to the languages.

1 Like

Thanks about the tip, I didn’t know so I will take a look and be careful when working with supervisor strategies.

Thank you, your solution solved it.
At this section of the code:

    children = [
      {Portal.Door, []}
    ]

I’ve made the mistake, after fixed the problem was gone.

The String.rjust/2 warning was helpful too.

I would love if somebody could send a PR updating it to latest Elixir, with formatter and everything else. Feel free to copy me in the PR and I will gladly give feedback!

6 Likes