my_supervisor.erl

text/x-erlang my_supervisor.erl — 2.1 KB

Continguts del fitxer

-module(my_supervisor).
-export([start_link/2, stop/1, add_children/2, list_children/1]).
-export([init/1]).

start_link(Name, ChildSpecList) ->
  register(Name, spawn_link(my_supervisor, init, [ChildSpecList])), ok.

init(ChildSpecList) ->
  process_flag(trap_exit, true),
  loop(start_children(ChildSpecList)).

start_children([]) -> [];
start_children([{M, F, A} | ChildSpecList]) ->
  case (catch apply(M,F,A)) of
    {ok, Pid} ->
      [{Pid, {M,F,A}}|start_children(ChildSpecList)];
    _ ->
      start_children(ChildSpecList)
  end.

add_children(Name, Children) ->
  Name ! {add, Children}.
  
list_children(Name) ->
	Name!list.


%% El bucle del supervisor espera en una recepci la clausula de sortida i els missatges de detenci. 
%% Si un fill acaba, el supervisor rep el seu senyal de sortida i el reinicia, i substitueix la seva 
%% entrada a la llista dels fills emmagatzemats a la variable ChildList:

restart_child(Pid, ChildList) ->
  {value, {Pid, {M,F,A}}} = lists:keysearch(Pid, 1, ChildList),
  {ok, NewPid} = apply(M,F,A),
  [{NewPid, {M,F,A}}|lists:keydelete(Pid,1,ChildList)].

loop(ChildList) ->
  receive
	{add, [{M,F,A}]} ->
		{ok, NewPid} = apply(M,F,A),
		loop([{NewPid, {M,F,A}}|ChildList]);
	list ->
		io:format('Fills .=~n'),
		llist_children(ChildList),
		loop(ChildList);
    {'EXIT', Pid, _Reason} ->
      NewChildList = restart_child(Pid, ChildList),
      loop(NewChildList);
    {stop, From}  ->
      From ! {reply, terminate(ChildList)}
  end.

%% Es pot aturar el supervisor amb la funci de client sincrn stop/1. En rebre el missatge d'aturada, 
%% el supervisor executa la funci 'terminate' tota la llista de la Variable ChildList, finalitzant tots
%% els fill un per un. Desprs d'haver acabat tots els fills, retorna l'tom 'ok'al procs que l'ha cridat:

stop(Name) ->
  Name ! {stop, self()},
  receive {reply, Reply} -> Reply end.

terminate([{Pid, _} | ChildList]) ->
  exit(Pid, kill),
  terminate(ChildList);
terminate(_ChildList) -> ok.


llist_children([]) -> ok;

llist_children([Child|ChildList]) ->
	io:format('~p~n',[Child]),
	llist_children(ChildList).