2016-02-28 55 views
1

你如何開始與simple_one_for_one主管的孩子? 我經歷溶胞書,目前在動態監督部分:http://learnyousomeerlang.com/supervisors#dynamic-supervision用simple_one_for_one主管開始孩子

筆者從孩子如下,但是我不知道在哪裏djembe定義:

1> supervisor:start_child(band_supervisor, [djembe, good]). 
Musician Janet Tennelli, playing the djembe entered the room 
{ok,<0.690.0>} 
2> supervisor:start_child(band_supervisor, [djembe, good]). 
{error,{already_started,<0.690.0>}} 

這裏是我的嘗試:

2> supervisor:start_link(band_supervisor, jamband). 
{ok,<0.40.0>} 
3> supervisor:start_child(band_supervisor, [djembe, good]). 

=ERROR REPORT==== 28-Feb-2016::03:52:56 === 
** Generic server <0.40.0> terminating 
** Last message in was {'EXIT',<0.33.0>, 
          {{noproc, 
           {gen_server,call, 
            [band_supervisor, 
            {start_child,[djembe,good]}, 
            infinity]}}, 
          [{gen_server,call,3, 
           [{file,"gen_server.erl"},{line,212}]}, 
          {erl_eval,do_apply,6, 
           [{file,"erl_eval.erl"},{line,673}]}, 
          {shell,exprs,7,[{file,"shell.erl"},{line,686}]}, 
          {shell,eval_exprs,7, 
           [{file,"shell.erl"},{line,641}]}, 
          {shell,eval_loop,3, 
           [{file,"shell.erl"},{line,626}]}]}} 
** When Server state == {state, 
          {<0.40.0>,band_supervisor}, 
          simple_one_for_one, 
          [{child,undefined,jam_musician, 
           {musicians,start_link,[]}, 
           temporary,1000,worker, 
           [musicians]}], 
          undefined,3,60,[],band_supervisor,jamband} 
** Reason for termination == 
** {{noproc,{gen_server,call, 
         [band_supervisor, 
         {start_child,[djembe,good]}, 
         infinity]}}, 
    [{gen_server,call,3,[{file,"gen_server.erl"},{line,212}]}, 
    {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,673}]}, 
    {shell,exprs,7,[{file,"shell.erl"},{line,686}]}, 
    {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]}, 
    {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]} 
** exception exit: {noproc,{gen_server,call, 
             [band_supervisor, 
             {start_child,[djembe,good]}, 
             infinity]}} 
    in function gen_server:call/3 (gen_server.erl, line 212) 

這裏如何監事看起來是:

-module(band_supervisor). 
-behaviour(supervisor). 

-export([start_link/1]). 
-export([init/1]). 

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

%% The band supervisor will allow its band members to make a few 
%% mistakes before shutting down all operations, based on what 
%% mood he's in. A lenient supervisor will tolerate more mistakes 
%% than an angry supervisor, who'll tolerate more than a 
%% complete jerk supervisor 
init(lenient) -> 
    init({one_for_one, 3, 60}); 
init(angry) -> 
    init({rest_for_one, 2, 60}); 
init(jerk) -> 
    init({one_for_all, 1, 60}); 
init(jamband) -> 
    {ok, {{simple_one_for_one, 3, 60}, 
     [{jam_musician, 
      {musicians, start_link, []}, 
      temporary, 1000, worker, [musicians]} 
     ]}}; 
init({RestartStrategy, MaxRestart, MaxTime}) -> 
    {ok, {{RestartStrategy, MaxRestart, MaxTime}, 
     [{singer, 
      {musicians, start_link, [singer, good]}, 
      permanent, 1000, worker, [musicians]}, 
      {bass, 
      {musicians, start_link, [bass, good]}, 
      temporary, 1000, worker, [musicians]}, 
      {drum, 
      {musicians, start_link, [drum, bad]}, 
      transient, 1000, worker, [musicians]}, 
      {keytar, 
      {musicians, start_link, [keytar, good]}, 
      transient, 1000, worker, [musicians]} 
     ]}}. 

這裏的音樂家:

-module(musicians). 
-behaviour(gen_server). 

-export([start_link/2, stop/1]). 
-export([init/1, handle_call/3, handle_cast/2, 
     handle_info/2, code_change/3, terminate/2]). 

-record(state, {name="", role, skill=good}). 
-define(DELAY, 750). 

start_link(Role, Skill) -> 
    gen_server:start_link({local, Role}, ?MODULE, [Role, Skill], []). 

stop(Role) -> gen_server:call(Role, stop). 

init([Role, Skill]) -> 
    %% To know when the parent shuts down 
    process_flag(trap_exit, true), 
    %% sets a seed for random number generation for the life of the process 
    %% uses the current time to do it. Unique value guaranteed by now() 
    random:seed(now()), 
    TimeToPlay = random:uniform(3000), 
    Name = pick_name(), 
    StrRole = atom_to_list(Role), 
    io:format("Musician ~s, playing the ~s entered the room~n", 
       [Name, StrRole]), 
    {ok, #state{name=Name, role=StrRole, skill=Skill}, TimeToPlay}. 

handle_call(stop, _From, S=#state{}) -> 
    {stop, normal, ok, S}; 
handle_call(_Message, _From, S) -> 
    {noreply, S, ?DELAY}. 

handle_cast(_Message, S) -> 
    {noreply, S, ?DELAY}. 

handle_info(timeout, S = #state{name=N, skill=good}) -> 
    io:format("~s produced sound!~n",[N]), 
    {noreply, S, ?DELAY}; 
handle_info(timeout, S = #state{name=N, skill=bad}) -> 
    case random:uniform(5) of 
     1 -> 
      io:format("~s played a false note. Uh oh~n",[N]), 
      {stop, bad_note, S}; 
     _ -> 
      io:format("~s produced sound!~n",[N]), 
      {noreply, S, ?DELAY} 
    end; 
handle_info(_Message, S) -> 
    {noreply, S, ?DELAY}. 

code_change(_OldVsn, State, _Extra) -> 
    {ok, State}. 

terminate(normal, S) -> 
    io:format("~s left the room (~s)~n",[S#state.name, S#state.role]); 
terminate(bad_note, S) -> 
    io:format("~s sucks! kicked that member out of the band! (~s)~n", 
       [S#state.name, S#state.role]); 
terminate(shutdown, S) -> 
    io:format("The manager is mad and fired the whole band! " 
       "~s just got back to playing in the subway~n", 
       [S#state.name]); 
terminate(_Reason, S) -> 
    io:format("~s has been kicked out (~s)~n", [S#state.name, S#state.role]). 

%% Yes, the names are based off the magic school bus characters 
%% 10 names! 
pick_name() -> 
    %% the seed must be set for the random functions. Use within the 
    %% process that started with init/1 
    lists:nth(random:uniform(10), firstnames()) 
    ++ " " ++ 
    lists:nth(random:uniform(10), lastnames()). 

firstnames() -> 
    ["Valerie", "Arnold", "Carlos", "Dorothy", "Keesha", 
    "Phoebe", "Ralphie", "Tim", "Wanda", "Janet"]. 

lastnames() -> 
    ["Frizzle", "Perlstein", "Ramon", "Ann", "Franklin", 
    "Terese", "Tennelli", "Jamal", "Li", "Perlstein"]. 

回答

1

learnyousomeerlang.com是一個很好的信息來源,但有時我覺得它太複雜。我通過閱讀supervisor OTP文檔直接瞭解到OTP的部分內容。如果你只是想了解動態的孩子,你可能不需要gen_server。見my simple implementation:通過簡單地調用estp_proj_sup:add(Name, Cfg)

-define(SHUTDOWN_TIMEOUT, 5000). 
-define(WORKER(I), {I, {I, start_link, []}, permanent, ?SHUTDOWN_TIMEOUT, worker, [I]}). 

然後添加孩子:

-module(estp_proj_sup). 
-behaviour(supervisor). 

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

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

-define(SERVER, ?MODULE). 

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

init([]) -> 
    Child = ?WORKER(estp_project), 
    {ok, {{simple_one_for_one, 3, 30}, [Child]}}. 

add(Name, Cfg) -> 
    Server = estp_project:server_name(Name), 
    State = [{name, Name}|Cfg], 
    case whereis(Server) of 
     undefined -> 
      add_child(Server, State); 
     Pid -> 
      delete_child(Server, Pid), 
      add_child(Server, State) 
    end. 

add_child(Server, State) -> 
    supervisor:start_child(?SERVER, [Server, State]). 

delete_child(Server, Pid) -> 
    ok = supervisor:terminate_child(?SERVER, Pid). 

,其動態孩子名字estp_project:server_name/1是這樣創建的:

server_name(Name) -> 
    Module = atom_to_binary(?MODULE, utf8), 
    Binary = atom_to_binary(Name, utf8), 
    binary_to_atom(<<Module/binary, <<"$">>/binary, Binary/binary>>, utf8). 

worker被定義爲在this code

process(Res) -> 
    %% Res contains parsed list of project names and their configurations 
    [set_project(Name, Cfg) || {Name, {ok, Cfg}} <- Res]. 

set_project(Name, Cfg) -> 
    case estp_proj_sup:add(Name, Cfg) of 
     {ok, _Pid} -> ok; 
     {error, _} = Err -> Err 
    end. 

不管怎麼說,我想你的榜樣,它似乎是工作:

4> {ok, S} = band_supervisor:start_link(jamband). 
{ok,<0.47.0>} 
5> supervisor:start_child(band_supervisor, [djembe, good]). 
Musician Wanda Terese, playing the djembe entered the room 
{ok,<0.49.0>} 
Wanda Terese produced sound! 
Wanda Terese produced sound! 
Wanda Terese produced sound! 
Wanda Terese produced sound! 
Wanda Terese produced sound! 
6> supervisor:start_child(band_supervisor, [djembe, good]). 
{error,{already_started,<0.49.0>}} 
Wanda Terese produced sound! 
Wanda Terese produced sound! 
+0

奇怪,現在的工作。一定是一些愚蠢的錯誤。不管怎麼說,多謝拉。 – drozzy