Links, Monitors & Fault Tolerance

When a process terminates abnormally, an exit signal is sent to all linked processes, which also die — unless they trap exits.

25.1 Links — bidirectional

When a process terminates abnormally, an exit signal is sent to all linked processes, which also die — unless they trap exits.

Pid = spawn_link(fun() -> exit(crash) end),     % atomically spawn + link
link(Pid), unlink(Pid).

25.2 Trapping exits

process_flag(trap_exit, true),
Pid = spawn_link(fun() -> exit(boom) end),
receive
    {'EXIT', Pid, Reason} -> io:format("Child exited: ~p~n", [Reason])
end.

25.3 Exit signal semantics

{'EXIT', Pid, normal} message kill (via exit(Pid, kill)) dies with reason killed dies anyway (untrappable) dies with same reason {'EXIT', Pid, Reason} message

exit(Pid, shutdown),   % send an exit signal to another process
exit(Pid, kill).       % brutal kill

25.4 Monitors — unidirectional

Monitors stack (multiple monitors → multiple DOWN messages) and don't affect the monitored process. Use monitors when you just want to *know*; use links when processes should *live and die together*.

Ref = monitor(process, Pid),
receive
    {'DOWN', Ref, process, Pid, Reason} -> {down, Reason}
end,
demonitor(Ref, [flush]),
{Pid2, Ref2} = spawn_monitor(fun() -> ok end).

25.5 Aliases (OTP 24+)

Prevents stray late replies after timeouts.

Alias = alias([reply]),     % reply-only address, auto-deactivates after one reply
Server ! {request, Alias},
receive {Alias, Reply} -> Reply end.

25.6 Let it crash & the error kernel

Separate worker code (does the job, may crash) from supervisor code (restarts workers).

Don't catch everything defensively — crash, log, and restart in a clean state.

Keep the critical state (the error kernel) small and well-protected.