4

Is there a way to tell a gen_server: "supervisor has initialised all gen_servers, now you can send then messages"?

I have a worker gen_server whose job is to set up states of other gen_servers in his supervision tree. If I just start sending messages in init function of my configuration server, sometimes it gets {noproc, _}. I suppose that means that config server was to fast: he sent messages before supervisor had enough time to start all workers. I fixed that by putting timer:sleep(500) in config_server:init(), which ensures all gen_server had enough time to initialise, but this seems like a inelegant solution.

Is there a proper way to do this?

Jonas
  • 121,568
  • 97
  • 310
  • 388
dijxtra
  • 2,681
  • 4
  • 25
  • 37

3 Answers3

3

Return tuple with timeout 0 from init. Then immediately after it returns, handle_info(timeout, State) will be called. In handle_info make some call which won't return until the supervisor finishes initialization (e.g. supervisor:which_children).

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Note: it's not possible to call `supervisor:which_children` in `init`, because before the supervisor knows a child was correctly initialized, the child calls `proc_lib:init_ack`. The timeout solution fixes this, but a `send_cast` also works. – Pindatjuh Jun 30 '11 at 11:36
0

in function init() call gen_server:cast(init, State). message "init" will be first in message queue

Andrei Sfat
  • 8,440
  • 5
  • 49
  • 69
amranello
  • 1
  • 1
0
info(PlayerId) ->
Pid = case global:whereis_name(util:getRegName({?MODULE, PlayerId})) of
    P when is_pid(P) ->
        P;
    _ ->
        {ok, P} = player_sup:start_child(PlayerId),
        P
end,
gen_server:call(Pid, info).

This is my case to handle this issue. This worker process is triggered only when it is requested.

Witeman
  • 49
  • 4