Monday, October 10, 2011

Erlang: Supervising two processes from a single supervisor

Only because this ate over an hour of my day today.

Below is a shell example of a supervisor that starts two child processes which are also supervisors.

-module(arti_sup).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).

%% ===================================================================
%% API functions
%% ===================================================================

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

%% ===================================================================
%% Supervisor callbacks
%% ===================================================================

init([]) ->
    Hip_Sup = ?CHILD(parser_sup , supervisor),
    ServiceSup = ?CHILD(service_sup , supervisor),

    Children = [ Hip_Sup, ServiceSup ],
    RestartStrategy = { one_for_one , 4, 9600},
    {ok, { RestartStrategy, Children } }. 

 
I have to other supervisors parser_sup and  and service_sup.

If you find that no matter what you change in this file doesn't seem to make a difference to which supervisor is being called, check that this supervisor itself is being started from the application filename_app.erl ,

If all goes well, you can use the sasl application to check the supervisor / launch information.

1> application:start(sasl).
ok

=PROGRESS REPORT==== 11-Oct-2011::01:59:07 ===
          supervisor: {local,sasl_safe_sup}
             started: [{pid,<0.41.0>},
                       {name,alarm_handler},
                       {mfargs,{alarm_handler,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,2000},
                       {child_type,worker}]
 

<removed for brevity...>


2> application:start(myapplication).
INIT parser supervisor
INIT service supervisor

=PROGRESS REPORT==== 11-Oct-2011::01:59:14 ===
          supervisor: {local,human_input_parser_sup}
             started: [{pid,<0.51.0>},
                       {name,human_input_parser_srv},
                       {mfargs,{human_input_parser_srv,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,5000},
                       {child_type,worker}]

=PROGRESS REPORT==== 11-Oct-2011::01:59:14 ===
          supervisor: {local,arti_sup}
             started: [{pid,<0.50.0>},
                       {name,human_input_parser_sup},
                       {mfargs,{human_input_parser_sup,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,5000},
                       {child_type,supervisor}]

=PROGRESS REPORT==== 11-Oct-2011::01:59:14 ===
          supervisor: {local,service_sup}
             started: [{pid,<0.53.0>},
                       {name,service_srv},
                       {mfargs,{service_srv,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,5000},
                       {child_type,worker}]

=PROGRESS REPORT==== 11-Oct-2011::01:59:14 ===
          supervisor: {local,arti_sup}
             started: [{pid,<0.52.0>},
                       {name,service_sup},
                       {mfargs,{service_sup,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,5000},
                       {child_type,supervisor}]

=PROGRESS REPORT==== 11-Oct-2011::01:59:14 ===
         application: arti
          started_at: nonode@nohost
ok

You can also use appmon to get a visualization of the supervisor tree with the command

3> appmon:start().
{ok,<0.55.0>}


This should present a graphical application which shows the supervisor/process trees currently running and is updated in real time.

No comments: