Hi, I have a DynamicSupervisor spawning 20 child processes. They work fine for a few minutes, and then all of them terminate unexpectedly. The supervisor doesn’t restart the processes even though I have the restart
option set to :permanent
. I’ve trapped exits of the child process, and indeed the terminate
callback is receiving a :shutdown
message. None of my code could potentially be shutting down the child processes, let alone all 20 of them simultaneously. All other GenServers are untouched, the parent process keeps running.
What could be causing such weird behaviour, and how can I get the DynamicSupervisor to restart its children?
The application is database-heavy, the workers constantly write to the database, hundreds inserts per second each. Perhaps this is somehow related? The child processes interact directly with Ecto with no intermediary processes.
defmodule App.Worker do
use GenServer, restart: :permanent
def start_link(args), do: GenServer.start_link(__MODULE__, args)
def start_new_worker() do
{:ok, pid} =
DynamicSupervisor.start_child(
App.WorkerSupervisor,
{__MODULE__, :no_args}
)
pid
end
@impl true
def terminate(reason, state) do
Logger.info("worker terminating, reason: #{inspect reason}")
end
end
application.ex:
defmodule App.Application do
use Application
def start(_type, _args) do
children = [
{DynamicSupervisor,
name: App.WorkerSupervisor, strategy: :one_for_one}
]
opts = [strategy: :one_for_one, name: App.Supervisor]
Supervisor.start_link(children, opts)
end
end
Thank you!