Supervisor dies with its child?

Supervisors are not meant to die, they are intended to run indefinitely, monitoring children.

I think the solution is to have your own GenServer to do this instead of a supervisor:

  • Give this new process whatever info it needs to start the children or at least to track their PIDs.
  • Let it invoke Process.monitor on each PID.
  • Let it handle the DOWN messages and shrink the list accordingly.
  • Terminate with :stop when the list is empty.

In order to make handling DOWN messages easier, I defined a record for it:
Record.defrecord :downmsg, :'DOWN', [:monitorRef, :type, :pid, :status]

The function heads for handling the DOWN messages in GenServer then look like this:

  • Good case: def handle_info(downmsg(status: :normal, pid: pid), data) do
  • Other cases: def handle_info(downmsg(status: status, pid: pid), data) do

This makes for a nice basic supervisor-like functionality and you can add the cleaning up of itself in the handle_info or any function, and either return a :noreply with the reduced list of PIDs as state or a :stop.

1 Like