关于erlang supervisor ,书上没有讲到的细节

今天写代码,想要得到一个supervisor下面挂的所有 worker数量,

我 通过dynamic的方式启动这些worker的:
    XXWorker = {"xx_worker" ++ util:uuid(),
             {xx_worker, start_link,[Task]},
             temporary, 5000, worker, dynamic},
    ?DEBUG("sup before call start_child~n", []),
    supervisor:start_child(xx_sup, XXWorker),
%xx_sup是一个已经启动的gen_server.

查 api,找到这个函数:which_children(SupRef) -> [{Id,Child,Type,Modules}]
但 是我自己用这个函数,却总是不能得到worker进程,
?VALUE(supervisor:which_children(xx_sup) ),
app_mon可以得到进程树,于是我想用app_mon里面的方法,未果,
后来看 supervisor的代码,
do_start_child_i(M, F, A) ->
    case catch apply(M, F, A) of
    {ok, Pid} when is_pid(Pid) ->
        {ok, Pid};
    {ok, Pid, Extra} when is_pid(Pid) ->
        {ok, Pid, Extra};
    ignore ->
        {ok, undefined};
    {error, Error} ->
        {error, Error};
    What ->
        {error, What}
    end.

handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) ->
    #child{mfa = {M, F, A}} = hd(State#state.children),
    Args = A ++ EArgs,
    case do_start_child_i(M, F, Args) of
    {ok, Pid} ->
        NState = State#state{dynamics =
                 ?DICT:store(Pid, Args, State#state.dynamics)},
        {reply, {ok, Pid}, NState};
    {ok, Pid, Extra} ->
        NState = State#state{dynamics =
                 ?DICT:store(Pid, Args, State#state.dynamics)},
        {reply, {ok, Pid, Extra}, NState};
    What ->
        {reply, What, State}
    end;
就 是说,要M:F(A) 返回的结果是个{ok, Pid} 才会被加入到DICT里面去,
supervisor:which_children()的 时候才会出来,
而我自己的xx_work:start_link() 只是简单的返回了ok.
再看看其它 gen_server:start_link(), 都是这样写的:
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
查gen_server源码,发现它的start_link 返回就是:  {'ok', pid()} | 'ignore' | {'error', term()}

于是,我把自己的 xx_work:start_link()  返回{ok, Pid}. 搞定.今天写代码,想要得到一个supervisor下面挂的所有 worker数量,

我 通过dynamic的方式启动这些worker的:
    XXWorker = {"xx_worker" ++ util:uuid(),
             {xx_worker, start_link,[Task]},
             temporary, 5000, worker, dynamic},
    ?DEBUG("sup before call start_child~n", []),
    supervisor:start_child(xx_sup, XXWorker),
%xx_sup是一个已经启动的gen_server.

查 api,找到这个函数:which_children(SupRef) -> [{Id,Child,Type,Modules}]
但 是我自己用这个函数,却总是不能得到worker进程,
?VALUE(supervisor:which_children(xx_sup) ),
app_mon可以得到进程树,于是我想用app_mon里面的方法,未果,
后来看 supervisor的代码,
do_start_child_i(M, F, A) ->
    case catch apply(M, F, A) of
    {ok, Pid} when is_pid(Pid) ->
        {ok, Pid};
    {ok, Pid, Extra} when is_pid(Pid) ->
        {ok, Pid, Extra};
    ignore ->
        {ok, undefined};
    {error, Error} ->
        {error, Error};
    What ->
        {error, What}
    end.

handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) ->
    #child{mfa = {M, F, A}} = hd(State#state.children),
    Args = A ++ EArgs,
    case do_start_child_i(M, F, Args) of
    {ok, Pid} ->
        NState = State#state{dynamics =
                 ?DICT:store(Pid, Args, State#state.dynamics)},
        {reply, {ok, Pid}, NState};
    {ok, Pid, Extra} ->
        NState = State#state{dynamics =
                 ?DICT:store(Pid, Args, State#state.dynamics)},
        {reply, {ok, Pid, Extra}, NState};
    What ->
        {reply, What, State}
    end;
就 是说,要M:F(A) 返回的结果是个{ok, Pid} 才会被加入到DICT里面去,
supervisor:which_children()的 时候才会出来,
而我自己的xx_work:start_link() 只是简单的返回了ok.
再看看其它 gen_server:start_link(), 都是这样写的:
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
查gen_server源码,发现它的start_link 返回就是:  {'ok', pid()} | 'ignore' | {'error', term()}

于是,我把自己的 xx_work:start_link()  返回{ok, Pid}. 搞定.
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页