[erlang-questions] supervisor children's pid

Vance Shipley <>
Wed May 18 06:48:25 CEST 2011

On Wed, May 18, 2011 at 12:37:02AM +0200, Roberto Ostinelli wrote:
}  currently, i'm calling supervisor:which_children/1 on the init function of
}  the gen_servers, and match the Ids to get the Child [Pid].

You can't call the supervisor from the init function of one of it's
own children.  You have to return from init/1 before that is possible.

What you can do is to return {ok, State, Timeout} from init/1 with
a Timeout value of 0 and go on with the initialization after the
supervisor has completed starting the children.  The attached example
uses a psuedo state to carry on with the initialization:

     1> supervisor:start_link(which_sup, []).
     Server=1, Siblings=[<0.36.0>,<0.35.0>]
     Server=2, Siblings=[<0.36.0>,<0.34.0>]
     Server=3, Siblings=[<0.35.0>,<0.34.0>]

}  is this the best strategy to achieve this?

Yes, use supervisor:which_children/1 to learn the siblings.

-------------- next part --------------


init(_Args) ->
	ChildSpecs = [server_spec(N) || N <- lists:seq(1, 3)],
	{ok, {{one_for_one, 10, 60}, ChildSpecs}}.

server_spec(N) ->
	StartMod = which_server,
	StartFunc = {gen_server, start_link, [StartMod, [self(), N], []]},
	{N, StartFunc, permanent, 4000, worker, [StartMod]}.

-------------- next part --------------

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

-record(state, {state, sup, siblings, n}).

init([Sup, N]) ->
	process_flag(trap_exit, true),
	{ok, #state{sup = Sup, state = init, n = N}, 0}.

handle_call(_Request, _From, State) ->
	{reply, ok, State}.

handle_cast(_Request, State) ->
	{noreply, State}.

handle_info(timeout, #state{sup = Sup, state = init, n = N} = State) ->
	Children = supervisor:which_children(Sup),
	SiblingSpecs = lists:keydelete(self(), 2, Children),
	Siblings = [Pid || {_, Pid, _, _} <- SiblingSpecs],
	io:fwrite("Server=~b, Siblings=~p~n", [N, Siblings]),
	{noreply, State#state{state = run, siblings = Siblings}};
handle_info(_Init, State) ->
	{noreply, State}.

terminate(_Reason, _State) ->

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

More information about the erlang-questions mailing list