关于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}. 搞定.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值