I have this code:
defmodule MyApp.JobRunner do
use DynamicSupervisor
alias MyApp.MyWorker
def start_link(_arg) do
DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(:ok) do
IO.puts("MyApp.JobRunner: init")
DynamicSupervisor.init(strategy: :one_for_one)
end
def add_new_task(my_task_id) do
child_spec = {MyWorker, {my_task_id}}
IO.puts("MyApp.JobRunner: child_spec > #{Kernel.inspect(child_spec)}")
res = DynamicSupervisor.start_child(__MODULE__, child_spec)
IO.puts("MyApp.JobRunner: add_new_task > #{Kernel.inspect(res)}")
res
end
Each time I'll call add_new_task(my_task_id)
with a new argument, it'll return an error
{:error, {{:badmatch, {:error, {:already_started, #PID<0.550.0>}}},
What's the matter? How is it "already started" if it's called a new argument each time?
MyApp.MyWorker
is a GenServer
. Can this error have to do with the way it's implemented in my project? I can provide the code
In MyWorker.start_link
do you have something like GenServer.start_link(__MODULE__, init_arg, name: __MODULE__)
? If so you'll only be able to start one child because the __MODULE__
macro gets replaced by MyWorker
and there can only be one process with that name.
You need a new name for each child. Since you initial state you are passing in is {my_task_id}
use that as the name:
defmodule MyWorker do
def start_link({name}) do
GenServer.start_link(__MODULE__, initial, name: name)
end
end