Erlang Dynamic supervisor启动gen

我有创建其他主管的root主管:

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

init([]) ->
    RestartStrategy = {one_for_one, 5, 600},
    ListenerSup =
            {popd_listener_sup,
            {popd_listener_sup, start_link, []},
             permanent, 2000, supervisor, [popd_listener]},

    Children = [ListenerSup],

    {ok, {RestartStrategy, Children}}.

我有gen_server - listener。 如何在supervisor创建时使用popd_listener_sup supervisor运行此gen_server?

谢谢。


根监督

-module(root_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1, shutdown/0]).

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

init(_Args) ->
     RestartStrategy = {one_for_one, 10, 60},
     ListenerSup = {popd_listener_sup,
          {popd_listener_sup, start_link, []},
          permanent, infinity, supervisor, [popd_listener_sup]},
     Children = [ListenerSup],
     {ok, {RestartStrategy, Children}}.    

% supervisor can be shutdown by calling exit(SupPid,shutdown)
% or, if it's linked to its parent, by parent calling exit/1.
shutdown() ->
     exit(whereis(?MODULE), shutdown).
     % or
     % exit(normal).

如果子进程是另一个主管,则应将子进程中的Shutdown设置为infinity以使子树有足够的时间关闭,并将Type设置为supervisor ,这就是我们所做的。

儿童监督员

-module(popd_listener_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).

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

init(_Args) ->
    RestartStrategy = {one_for_one, 10, 60},
    Listener = {ch1, {ch1, start_link, []},
            permanent, 2000, worker, [ch1]},
    Children = [Listener],
    {ok, {RestartStrategy, Children}}.

在这里,在儿童规范中,我们将Shutdown值设置为2000 。 一个整数超时值意味着管理程序将通过调用exit(Child,shutdown)来告诉子进程终止,然后等待从子进程返回原因关闭的退出信号。

倾听者

-module(ch1).
-behaviour(gen_server).

% Callback functions which should be exported
-export([init/1]).
-export([handle_cast/2, terminate/2]).

% user-defined interface functions
-export([start_link/0]).

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

init(_Args) ->
     erlang:process_flag(trap_exit, true),
     io:format("ch1 has started (~w)~n", [self()]),
     % If the initialization is successful, the function
     % should return {ok,State}, {ok,State,Timeout} ..
     {ok, []}.

handle_cast(calc, State) ->
     io:format("result 2+2=4~n"),
     {noreply, State};
handle_cast(calcbad, State) ->
     io:format("result 1/0~n"),
     1 / 0,
     {noreply, State}.

terminate(_Reason, _State) ->
     io:format("ch1: terminating.~n"),
     ok.

来自Erlang / OTP文档:

如果gen_server是监督树的一部分并且由其监督者命令终止,则如果满足以下条件,则将使用Reason=shutdown调用功能Module:terminate(Reason, State)

  • gen_server已被设置为陷阱出口信号,并且
  • 主管的子规范中定义的关闭策略
    是整数超时值,不是
    brutal_kill。
  • 这就是为什么我们在Module:init(Args)调用erlang:process_flag(trap_exit, true)的原因。

    样品运行

    启动root管理员:

    1> root_sup:start_link().
    ch1 has started (<0.35.0>)
    {ok,<0.33.0>}
    

    根监督者运行并自动启动它的子进程,在我们的情况下是子监督员。 儿童监督员反过来开始其子过程; 我们的例子中只有一个孩子, ch1

    让我们让ch1评估正常代码:

    2> gen_server:cast(ch1, calc).
    result 2+2=4
    ok
    

    现在一些不好的代码:

    3> gen_server:cast(ch1, calcbad).
    result 1/0
    ok
    ch1: terminating.
    
    =ERROR REPORT==== 31-Jan-2011::01:38:44 ===
    ** Generic server ch1 terminating 
    ** Last message in was {'$gen_cast',calcbad}
    ** When Server state == []
    ** Reason for termination == 
    ** {badarith,[{ch1,handle_cast,2},
                  {gen_server,handle_msg,5},
                  {proc_lib,init_p_do_apply,3}]}
    ch1 has started (<0.39.0>)
    4> exit(normal).
    ch1: terminating.
    ** exception exit: normal
    

    您可能会看到子进程ch1由子监督器popd_listener_sup重新启动(通知ch1 has started (<0.39.0>) )。

    由于我们的shell和root supervisor是双向链接的(call supervisor:start_link ,不是supervisor:start在root supervisor函数start_link/0 ), exit(normal)导致root supervisor关闭,但其子进程有一些时间清理。

    链接地址: http://www.djcxy.com/p/38249.html

    上一篇: Erlang Dynamic supervisor start gen

    下一篇: server processes with timeout