Регистрация ребенка в процессе, который инициировал вызов start_child - PullRequest
5 голосов
/ 03 декабря 2010

У меня есть логический модуль, который говорит супервизору запустить дочерние процессы. Мне нужно хранить pid этих детей в состоянии логических модулей. Но мне также нужно обновить дочерний pid, если супервизор перезапустит его.

Так что я не могу использовать pid возвращаемого значения из вызова start_child, так как это даст мне pid только при первом запуске, а не при перезапуске. Прямо сейчас я заставляю дочерний процесс вызывать функцию регистра (обновляет состояние с новым pid) в логическом модуле из дочерней функции init. Таким образом, логический модуль может обновлять pid в своем состоянии при каждом перезапуске процесса. Логический модуль является gen_server, и я выполняю приведение, когда регистрирую дочерний процесс.

Может кто-нибудь увидеть проблему с этим и есть ли другой, более "правильный" способ сделать это?

1 Ответ

6 голосов
/ 03 декабря 2010

Одна проблема в том, что у вас есть ChildPid, и ребенок может быть уже мертв.Поэтому отправка сообщения через cast будет означать, что сообщение потеряно.И через call вы столкнетесь с {'EXIT', noproc}, если не поймаете его из call.Ваше решение должно принимать во внимание, что Pid может быть давно прошло, как только вы отправите сообщение.Обычно игнорируя потерянное сообщение, сбивая себя или устраняя проблему, а затем продолжая.

Есть несколько вариантов.Это свободный список:

  • Делай, как делаешь.Пусть дети зарегистрируются.
  • Пусть у логического модуля есть monitor на ребенке.Таким образом, вы узнаете, умирает ли он.
  • Используйте Erlang Solutions * Модуль 1018 * gproc : https://github.com/esl/gproc, который обеспечивает удобный интерфейс для отслеживания таблицы ETSинформации.Обратите внимание, что вы можете найти pid в gproc и дождаться его прибытия, если процесс только перезапускается.
  • Используйте supervisor:which_children, чтобы найти соответствующего потомка.
  • RollВаша собственная таблица ETS как вариант gproc
  • локальные имена должны быть атомами, но глобально зарегистрированными именами может быть любой термин (они хранятся внутри втаблицу ETS, похожую на таблицу gproc, см. global_name_server в kernel/stdlib).Используйте глобальную структуру для отслеживания рассматриваемых пидов.
...