Gen_server работает?

Есть ли способ сообщить gen_server: «супервизор инициализировал все gen_servers, теперь вы можете отправлять сообщения»?

У меня есть рабочий gen_server, чья работа заключается в настройке состояний других gen_server в его дереве надзора. Если я просто начинаю отправлять сообщения в функции инициализации моего сервера конфигурации, иногда он получает {noproc, _}. Я полагаю, это означает, что конфигурационный сервер был слишком быстрым: он отправил сообщения до того, как супервизор успел запустить всех рабочих. Я исправил это, поместив timer: sleep (500) в config_server: init (), что гарантирует, что у всего gen_server будет достаточно времени для инициализации, но это кажется неэлегантным решением.

Есть ли правильный способ сделать это?


person dijxtra    schedule 25.06.2011    source источник


Ответы (3)


Вернуть кортеж с таймаутом 0 из init. Затем сразу после его возврата будет вызван handle_info(timeout, State). В handle_info сделайте некоторый вызов, который не вернется, пока супервизор не завершит инициализацию (например, supervisor:which_children).

person Alexey Romanov    schedule 25.06.2011
comment
Примечание: невозможно вызвать supervisor:which_children в init, потому что до того, как супервизор узнает, что дочерний элемент был правильно инициализирован, дочерний элемент вызывает proc_lib:init_ack. Решение по тайм-ауту исправляет это, но send_cast также работает. - person Pindatjuh; 30.06.2011

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).

Это мой случай, чтобы решить эту проблему. Этот рабочий процесс запускается только по запросу.

person Witeman    schedule 25.06.2011

в функции init() call gen_server:cast(init, State). сообщение "init" будет первым в очереди сообщений

person amranello    schedule 25.06.2011