Skip to content

Instantly share code, notes, and snippets.

@kylethebaker
Created September 3, 2017 10:15
Show Gist options
  • Save kylethebaker/7e0af88507ab27c3a9b4ec647966732a to your computer and use it in GitHub Desktop.
Save kylethebaker/7e0af88507ab27c3a9b4ec647966732a to your computer and use it in GitHub Desktop.
Kent - Concurrent Programming in Erlang - Week 2
-module(super).
-export([start/0, init/0]).
%% Starts the supervisor in it's own process
start() ->
spawn(super, init, []).
%% Initializes the supervisor with it's children
init() ->
process_flag(trap_exit, true),
Strategy = one_for_one,
Children = [
{echo, {echo, listener, []}},
{talk, {talk, worker, []}}
],
Spawns = lists:foldl(fun spawn_child/2, [], Children),
loop(Spawns, Strategy).
%% Spawns a child process and tracks it in the Spawns registry
spawn_child(Definition, Spawns) ->
spawn_child(Definition, Spawns, "Initializing").
spawn_child({Name, {M, F, A}} = PDef, Spawns, Reason) ->
Pid = spawn_link(M, F, A),
register(Name, Pid),
io:format("Spawning new child with pid ~w as '~w'. Reason: ~s~n", [Pid, Name, Reason]),
[{Pid, PDef} | Spawns].
%% Loops waiting for exit signals
loop(Spawns, Strategy) ->
ChildPids = lists:map(fun ({Pid, _}) -> Pid end, Spawns),
receive
{'EXIT', Pid, Reason} ->
% only handle EXIT signals from processes that are our children
case lists:member(Pid, ChildPids) of
true ->
NewSpawns = handle_exit(Pid, Reason, Spawns, Strategy),
loop(NewSpawns, Strategy);
_ ->
loop(Spawns, Strategy)
end
end.
%% Handles one_for_one strategy: simply restart the dead process
handle_exit(OldPid, Reason, OldSpawns, one_for_one) ->
{value, {_, PDef}, Spawns} = lists:keytake(OldPid, 1, OldSpawns),
spawn_child(PDef, Spawns, Reason).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment