I have a dynamic supervisor that starts a gen server that should terminate itself after a specified time. However, the supervisor seems to restart the process, even when restart option is set to transient.
Here’s the relevant code (redacted so there may be errors, but you’ll get the idea):
Dynamic supervisor:
def init(:ok) do
DynamicSupervisor.init(strategy: :one_for_one, restart: :transient)
end
def start_genserver() do
spec = %{
start: {Module.Name, :start_link, []},
restart: :transient
}
DynamicSupervisor.start_child(__MODULE__, spec)
end
in the gen server:
@impl true
def init(state) do
Process.send_after(self(), :terminate, 3_000)
{:ok, state}
end
@impl true
def handle_info(:terminate, state) do
{:stop, :normal, state}
end
However the Gen Server process keeps coming back with a different PID. What am I missing here?
I think you may have redacted something important, because I can’t reproduce the behavior you’re seeing. This script can be run with just elixir foo.exs:
defmodule FooSupervisor do
use DynamicSupervisor
def start_link(init_arg) do
DynamicSupervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
end
def init(:ok) do
DynamicSupervisor.init(strategy: :one_for_one, restart: :transient)
end
def start_genserver() do
spec = %{
id: "nope",
start: {FooWorker, :start_link, []},
restart: :transient
}
IO.puts("starting child")
DynamicSupervisor.start_child(__MODULE__, spec)
end
end
defmodule FooWorker do
use GenServer
def start_link() do
GenServer.start_link(__MODULE__, [])
end
@impl true
def init(state) do
IO.puts("child init")
Process.send_after(self(), :terminate, 3000)
{:ok, state}
end
@impl true
def handle_info(:terminate, state) do
IO.puts("child stop")
{:stop, :normal, state}
end
end
FooSupervisor.start_link(:ok)
FooSupervisor.start_genserver()
Process.sleep(:infinity)