Erlang Dynamic supervisor start gen_server
-
27-10-2019 - |
Вопрос
У меня есть корневой супервизор, который создает другого супервизора:
родовое слово А у меня есть gen_server - listener.Как я могу запустить этот gen_server с супервизором popd_listener_sup
, когда супервизор создан?
Спасибо.
Решение
Корневой супервизор
родовое слово Если дочерний процесс является другим супервизором, для параметра Shutdown
в дочерней спецификации должно быть установлено значение infinity
, чтобы дать поддереву достаточно времени для завершения работы, а для параметра Type
необходимо установить значение supervisor
, что мы и сделали.
Дочерний руководитель
родовое слово Здесь, в дочерней спецификации, мы устанавливаем значение Shutdown
равным 2000
. Целочисленное значение тайм-аута означает, что супервизор скажет дочернему процессу завершить работу, вызвав exit(Child,shutdown)
, а затем дождется сигнала выхода с указанием причины завершения работы дочернего процесса.
Слушатель
родовое словоИз документации Erlang / OTP:
<цитата> Если gen_server является частью
дерево наблюдения и упорядочивается по его
супервизор прекратить, функция
сгенерировать кодовый код будет
вызываться с помощью Module:terminate(Reason, State)
, если
применяются следующие условия:
- был настроен код
Reason=shutdown
для перехвата сигналов выхода, и - стратегия выключения, как определено в спецификации дочернего супервизора
- целочисленное значение тайм-аута, а не
brutal_kill.
Вот почему мы назвали gen_server
в erlang:process_flag(trap_exit, true)
.
Пример выполнения
Запуск корневого супервизора:
родовое слово Корневой супервизор запускается и автоматически запускает свои дочерние процессы, в нашем случае дочерний супервизор. Дочерний супервизор, в свою очередь, запускает свои дочерние процессы; в нашем случае у нас есть только один дочерний элемент, Module:init(Args)
.
Давайте заставим ch1
оценить нормальный код:
А теперь плохой код:
родовое слово Как вы можете видеть, дочерний процесс ch1
был перезапущен дочерним супервизором ch1
(обратите внимание на popd_listener_sup
).
Поскольку наша оболочка и корневой супервизор связаны двунаправленно (вызов ch1 has started (<0.39.0>)
, а не supervisor:start_link
в функции корневого супервизора supervisor:start
), start_link/0
привел к завершению работы корневого супервизора, но его дочерние процессы имели некоторое время для очистки.