Skip to content
Erlang

Links, Exit-Trapping und „Let It Crash“

Verwendet link und trap_exit, um Prozessabstürze zu erkennen und zu beheben.

#link#exit#fault-tolerance

Code

erlang
-module(keeper).
-export([start/0, child/0]).

start() ->
    process_flag(trap_exit, true),         % convert EXIT signals to messages
    Pid = spawn_link(fun child/0),         % spawn AND link atomically
    keeper_loop(Pid).

keeper_loop(Pid) ->
    receive
        {'EXIT', Pid, Reason} ->
            io:format("child died with ~p, restarting~n", [Reason]),
            NewPid = spawn_link(fun child/0),
            keeper_loop(NewPid);
        {'EXIT', _Other, _Reason} ->
            %% some other linked process died; ignore
            keeper_loop(Pid);
        {stop, From} ->
            exit(Pid, shutdown),
            From ! ok
    end.

child() ->
    timer:sleep(rand:uniform(5000)),
    case rand:uniform(3) of
        1 -> erlang:error(bad_thing);      % crash on purpose
        2 -> exit(normal);                 % 'normal' exits don't propagate
        _ -> exit(bad_luck)                % abnormal exit
    end.

% With trap_exit=true the keeper survives all of these because
% exit signals arrive as {'EXIT', Pid, Reason} messages.