Mix.install([
{:kino, "~> 0.7.0"}
])
defmodule Worker do
use GenServer
def child_spec(pid) do
%{
id: Worker,
start: {Worker, :start_link, [pid]},
restart: :transient
}
end
defp via(pid) do
{:via, Registry, {WorkerRegistry, pid}}
end
def start_link(pid) do
GenServer.start_link(__MODULE__, pid, name: via(pid))
end
def init(pid) do
IO.inspect("WORKER")
:timer.send_interval(1000, self(), :reply) |> IO.inspect()
{:ok, %{manager_pid: pid}}
end
def handle_info(:reply, %{manager_pid: pid} = state) do
result = :rand.uniform(10)
send(pid, {:result, result})
{:noreply, state}
end
end
defmodule MySupervisor do
use Supervisor
def start_link do
start_link([])
end
def start_link(_) do
Supervisor.start_link(__MODULE__, [], name: MySupervisor)
end
def init(_) do
children = [
{Registry, keys: :unique, name: WorkerRegistry},
{DynamicSupervisor, name: WorkerSupervisor},
{Manager, []}
]
Supervisor.init(children, strategy: :one_for_one)
end
end
defmodule Manager do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init(_) do
state =
case DynamicSupervisor.start_child(WorkerSupervisor, Worker.child_spec(self())) do
{:ok, pid} ->
IO.inspect(pid, label: "WORKER")
Process.monitor(pid)
%{worker: pid}
err ->
IO.inspect(err, label: "ERROR")
%{}
end
{:ok, state}
end
def handle_info({:result, result}, state) do
IO.inspect(result, label: "RESULTS")
{:noreply, state}
end
def handle_info({:DOWN, ref, :process, pid, _}, %{worker: pid} = state) do
Process.demonitor(ref)
IO.inspect("Worker Down: #{inspect(pid)}")
{:noreply, state}
end
end
{:ok, sup} = MySupervisor.start_link()
sup
case Manager.start_link([]) do
{:ok, pid} -> pid
{:error, {:already_started, pid}} -> pid
end