Let's say I have a simple module
defmodule MyWorker do
def do_long_running_work(a, b, c) do
# ......
end
end
And DynamicSupervisor
defmodule MyDynamicSupervisor do
use DynamicSupervisor
def start_link(_arg) do
DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(:ok) do
DynamicSupervisor.init(strategy: :one_for_one)
end
def add_my_worker(worker_name, game_id) do
child_spec = {MyWorker, {worker_name, game_id}}
DynamicSupervisor.start_child(__MODULE__, child_spec)
end
def remove_my_worker(worker_pid) do
DynamicSupervisor.terminate_child(__MODULE__, worker_pid)
end
def children do
DynamicSupervisor.which_children(__MODULE__)
end
def count_children do
DynamicSupervisor.count_children(__MODULE__)
end
end
The documentation says the MyWorker has to has have a start_link method. Moreover, the examples there suggest that MyWorker be GenServer. Altough it could also instead contain child_spec without having to use GenServer
However, MyWorker would be doing a long-running a job in do_long_running_work() -- the one which could last hours. Whereas GenServer isn't meant to run long-running jobs in itself, right?
How would I then go about running MyWorker then? What would a simple implementation of MyWorker look like?
What would start_link look like it it wasn't a GenServer in my case?
And there'd be also thousands of instances of MyWorker created and run via MyDynamicSupervisor.
I don't want to simply create tasks. I want a) manage them b) see the state of each one c) one how many there're d) have a supervisor to restart them if need be. At runtime, dynamically.
What DynamicSupervisor is for then?
No. The
child specificationtells the DynamicSupervisor how to start the child:https://hexdocs.pm/elixir/1.14.4/Supervisor.html#module-child-specification
For instance:
You could call
add_my_worker()like this:The DynamicSupervisor would then call: