Stopping child (GenServer) in DynamicSupervisor gracefully without restarting it


I have a GenServer running as a child under DynamicSupervisor. The GenServer does something and using info status message I check it’s state and when the GenServer finished it’s job, I return

{:stop, :normal, state}

from it. And I want to stop the process, but the DynamicSupervisor restarts it again. I tried to send a message before returning the {:stop… } and in the handler of the message call terminate_child, but the supervisor seems to be faster restarting the child before terminating it.

I want the process to be supervised for error reasons, so when there is a problem, it restarts it, but I want to end gracefully when finished without restarting it.

What can I do or what’s best way how to handle such scenario?

Thanks in advance.


What child spec do You pass to dynamic supervisor to start your worker?

Here is one I use that does not imply worker restart…

    spec = %{
      id: name,
      start: {Worker, :start_link, [args]},
      restart: :temporary,
      type: :worker
1 Like

Hey, I’m using the Module child spec.

    {Service.Manager, [id: id, opts: opts]}

I think it’s the restart: option. now I see in the docs

:transient - the child process is restarted only if it terminates abnormally, i.e., with an exit reason other than :normal , :shutdown , or {:shutdown, term} .

This seems to be what I was looking for, thanks for the hint with restart: option!


I am using restart: :temporary because I delegate the monitoring task to another process… making my dynamic supervisor superdumb.

But I would use :transient as well in your case :slight_smile:

1 Like

is it possible to find out? if/how it terminates abnormally? like the reason of why it terminated abnormally ?

I think it should be in the logs. I keep getting abnormal termination messages in the sentry spam that the company I work subscribed me to.