Skip to content

Instantly share code, notes, and snippets.

@Xdeon
Created July 8, 2020 08:44
Show Gist options
  • Save Xdeon/2029d2527a86aa58d29f54a816dcbcee to your computer and use it in GitHub Desktop.
Save Xdeon/2029d2527a86aa58d29f54a816dcbcee to your computer and use it in GitHub Desktop.
naive supervisor
-module(echo).
-export([listener/0]).
listener() ->
receive
{Pid, M} ->
io:format("~w echoed.~n", [M]),
Pid ! M,
listener()
end.
-module(super).
-export([start/0, super/0]).
%% without supervisor:
%% When talk process is killed, echo process is not affected and will keep waiting.
%% When echo process is killed, talk process will crash as well.
%% because it can not find the process under the name 'echo' anymore, and the send operation fails.
%% with supervisor:
%% When talk process is killed, echo process is not affected and will keep waiting.
%% The supervisor immediately restart a new talk process and the talk&echo continues.
%% When echo process is killed, because of the 1 sec sleeping in the supervisor,
%% echo process is not restarted immediately.
%% As a result, talk process will crash as well for the same reason stated above.
%% Then a new echo process is started and registered.
%% After that, a new talk process is started. And the talk&echo restarts.
%% If there is no sleeping in the supervisor, echo process will be restarted and registered right after its exit.
%% So it is very likely that talk process will not notice this due to its own sleeping.
%% The talk&echo will continue without restarting.
start() ->
spawn(?MODULE, super, []).
super() ->
process_flag(trap_exit, true),
E = spawn_link(echo, listener, []),
register(echo, E),
io:format("echo spawned.~n"),
T = spawn_link(talk, worker, []),
register(talk, T),
io:format("talk spawned as Pid ~w.~n", [whereis(talk)]),
loop(E, T).
loop(E, T) ->
receive
{'EXIT', T, _} ->
NewT = spawn_link(talk, worker, []),
register(talk, NewT),
io:format("talk re-spawned as Pid ~w.~n", [whereis(talk)]),
loop(E, NewT);
{'EXIT', E, _} ->
timer:sleep(1000),
NewE = spawn_link(echo, listener, []),
register(echo, NewE),
io:format("echo re-spawned.~n"),
loop(NewE, T)
end.
-module(talk).
-export([worker/0]).
worker() ->
work(0).
work(N) ->
Msg = {self(), N},
echo ! Msg,
io:format("~w sent.~n", [Msg]),
receive
_Reply ->
timer:sleep(500),
work(N+1)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment