supervisor add child的时候返回 {error,ok}

32 views
Skip to first unread message

自由天堂

unread,
Oct 26, 2013, 9:24:52 PM10/26/13
to erlang...@googlegroups.com
遇到一个很奇怪的问题,简化一下就是一个supervisor用simple_one_for_one来管一组gen server

Eshell V5.10.2  (abort with ^G)
1> c(ac).
{ok,ac}
2> c(ac_sup).
{ok,ac_sup}
3> ac_sup:start_link().
{ok,<0.56.0>}

但是,当我add child时,返回 {error,ok}
4> ac_sup:start_child().

=INFO REPORT==== 27-Oct-2013::09:18:46 ===
start link: "user", "host", 10
=INFO REPORT==== 27-Oct-2013::09:18:46 ===
init: "user", "host"
{error,ok}

我看了一下proc info,发现add child以后supervisor里面没有放入work进程的信息(下面标粗体的undefined应该是一个dictionary才对)

y(0)     []
y(1)     infinity
y(2)     supervisor
y(3)     {state,{local,ac_sup},simple_one_for_one,[{child,undefined,ac,{ac,start_link,[]},transient,2000,worker,[ac]}],undefined,10,60,[],ac_sup,[]}
y(4)     ac_sup
y(5)     <0.42.0>

但是work进程和monitor的连接倒是建立了

=proc:<0.58.0>
State: Waiting
Name: 'channel@10'
Spawned as: proc_lib:init_p/5
Spawned by: <0.56.0>
Started: Sun Oct 27 09:18:46 2013
Message queue length: 0
Number of heap fragments: 0
Heap fragment data: 0
Link list: [<0.56.0>]
Dictionary: [{'$initial_call',{ac,init,1}},{'$ancestors',[ac_sup,<0.42.0>]}]

完全不理解,求帮助

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
附上完整的代码:

%% ac.erl
-module(ac).
-behaviour(gen_server).

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

%% Gen Server callbacks
-export([init/1,handle_call/3,handle_cast/2,handle_info/2]).
-export([code_change/3,terminate/2]).

-define(SERVER(ChannelId), list_to_atom("channel@" ++ integer_to_list(ChannelId))).

start_link(User, Host, ChannelId) ->  error_logger:info_msg("start link: ~p, ~p, ~p", [User,Host,ChannelId]),
  gen_server:start_link({local, ?SERVER(ChannelId)}, ?MODULE, [User,Host],[]),
  ok.

%% Gen Server callbacks
init([User, Host]) ->
  error_logger:info_msg("init: ~p, ~p~n", [User,Host]),
  {ok, [User,Host]}.

handle_call(Request, _From, State) ->
  error_logger:info_msg(": ~p", [Request]),
  {reply, none, State}.

handle_info(Info, State) ->
  error_logger:info_msg(": ~p", [Info]),
  {noreply, State}.

handle_cast(Request, State) ->
  error_logger:info_msg(": ~p", [Request]),
  {noreply, State}.

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

terminate(Reason, State) ->
  io:format("Reason: ~p~n", Reason),
  terminated.

%% ac_sup.erl
-module(ac_sup).

-behaviour(supervisor).

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

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

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

start_child() ->
  User="user",
  Host="host",
  ChannelId=10,
  supervisor:start_child(?MODULE,[User, Host,ChannelId]).

init([]) ->
  Client = { 
    ac, 
    { ac, start_link, []},
    transient,
    2000,
    worker, 
    [ac]
  },
  {ok, { {simple_one_for_one, 10, 60}, [Client]} }.

Lihe Wang

unread,
Oct 26, 2013, 9:49:37 PM10/26/13
to erlang...@googlegroups.com
文档好好看了没有啊?Client的start_link的参数根本没添啊。start_child也不是你这么用的吧?正常启动监控树是用不着写start_child的。


2013/10/27 自由天堂 <li.j...@gmail.com>

--
您收到此邮件是因为您订阅了 Google 网上论坛的“Erlang China”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到 erlang-china...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/groups/opt_out。

自由天堂

unread,
Oct 27, 2013, 12:30:19 PM10/27/13
to erlang...@googlegroups.com
通过读supervisor的源码已经解决了问题,不是你说的那里。

错误在这里:

start_link(User, Host, ChannelId) ->  error_logger:info_msg("start link: ~p, ~p, ~p", [User,Host,ChannelId]),
  gen_server:start_link({local, ?SERVER(ChannelId)}, ?MODULE, [User,Host],[]),
  ok.

最后一行返回ok,而supervisor会根据这个返回值进行分派,最后在这里——

%% supervisor.erl

  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.

变成了 ok -> {error, ok} ,所以是返回码没有遵循设计要求的原因


在 2013年10月27日星期日UTC+8上午9时49分37秒,Wang Lihe写道:

Min Zhou

unread,
Oct 29, 2013, 2:43:01 AM10/29/13
to erlang...@googlegroups.com
D

Sent from my iPhone
Reply all
Reply to author
Forward
0 new messages