I am trying to start the below workers in a Supervisor that I am calling in application module in mix.exs

Like this

defmodule AppStarter do
import Supervisor.Spec
def start(_type,_args) do
    children=[
        worker(TPMod1,[],[]),
        worker(TPMod2,[],[])
    ]
    opts=[strategy: :one_for_one, name: HelloVisor]
    Supervisor.start_link(children,opts)
end


end

One of my module is GenServer and another I kept a simple listening process.

defmodule TPMod1 do

def start_link() do
 IO.puts "started TPMod1"
 listen()
end



def listen() do
  receive do
    _ -> :ok
  end
  listen()
end

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


end

Problem is it get stuck and doesn't start the worker 2 TPMod2 I tried doing in TPMod1's start_link()

def start_link() do
 IO.puts "started TPMod1"
 Task.async(&listen/0)
end

But that give me this

** (Mix) Could not start application tproject: AppStarter.start(:normal, []) returned an error: shutdown: failed to start child: TPMod1 ** (EXIT) %Task{owner: #PID<0.143.0>, pid: #PID<0.144.0>, ref: #Reference<0.2187290957.3420192769.212288>}

I can make it GenServer and make it work but how can we start a simple worker? And why supervisor is not restarting it again? not infinitly but some times? It should have at least tried restarting and fail. Please suggest other improvements too if any.

1 Answers

1
m3characters On Best Solutions

The supervisor expects the children to return {:ok, pid}, :ignore or {:error, reason}.

It hangs because when the supervisor runs the start_link function on your worker, it executes (as himself), listen which sets a receive block, so it gets stuck there. When you use the gen_* module's start_link and friends, it takes care of spawning, returning correctly etc.

In your case you could switch:

def start_link() do
 IO.puts "started TPMod1"
 listen()
end

to:

def start_link() do
 pid = spawn(__MODULE__, :listen, [])
 {:ok, pid}
end

And this should do it.