Hi all,
Assume I have two processes: Parent and Child, Child is a GenServer. Parent launches Child, and Child must react when Parent dies.
Normally, I would start Child with start_link
, set the Process.flag(:trap_exit, true)
and just handle the message in terminate
. But I need the Child state on the exit handler function, which is not provided with terminate
.
I managed to do it, but I am not sure my approach is the best available - I am sure there is a better way to do it below are essential parts of my code.
Parent runs the child with the simple start
function, passing own PID:
{:ok, pid} = Child.start({%{}, self()})
Child starts monitoring the parent on initialization. I added check if the parent is still alive in case it dies in the meantime:
def init({state, parent_pid}) do
if Process.alive?(parent_pid) do
Process.monitor(parent_pid)
else
Process.exit(self(), :normal)
end
{:ok, state}
end
And now I can handle the :DOWN
message from the monitor:
def handle_info({:DOWN, _ref, :process, _pid, {_reason, _state}}, state) do
# ... all the stuff needed to run before commit suicide
parent_died(state)
Process.exit(self(), :normal)
end
It works, and I have an access to the Childs state in parent_died/1
function. But is it a good approach to archive it? I especially don’t like using Process.exit/2
here. Normally OTP is more elegant than that…