[erlang-questions] supervisor children's pid
Vance Shipley
vances@REDACTED
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>]
{ok,<0.33.0>}
} is this the best strategy to achieve this?
Yes, use supervisor:which_children/1 to learn the siblings.
--
-Vance
-------------- next part --------------
-module(which_sup).
-behaviour(supervisor).
-export([init/1]).
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 --------------
-module(which_server).
-behaviour(gen_server).
-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) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
More information about the erlang-questions
mailing list