#erlang #erlang-supervisor
Вопрос:
в Эрланге у меня есть супервизор-дерево процессов, содержащее одно, которое принимает соединения tcp/ip. Для каждого входящего соединения я запускаю новый процесс. Должен ли этот процесс быть добавлен в дерево супервизора или нет?
С уважением, Стив
Ответ №1:
Да, вам следует добавить эти процессы в иерархию надзора, поскольку вы хотите, чтобы они были корректно/корректно завершены при остановке вашего приложения. (В противном случае вы закончите утечкой подключений, которые выйдут из строя, поскольку инфраструктура приложений, от которой они зависят, была отключена).
Вы могли бы создать simple_one_for_one
, скажем, руководителя стратегии yourapp_client_sup
, у которого есть дочерняя спецификация {Id, {yourapp_client_connection, start_link_with_socket, []}, Restart, Shutdown, worker, temporary}
. temporary
Тип здесь важен, потому что обычно для обработчика соединений нет полезной стратегии перезапуска — вы не можете подключиться к клиенту, чтобы перезапустить соединение. temporary
это приведет к тому, что супервизор сообщит о выходе обработчика подключения, но в противном случае проигнорирует его.
Процесс, который это сделает gen_tcp:accept
, затем создаст процесс обработчика соединений, выполнив supervisor:start_child(yourapp_client_sup, [Socket,Options,...])
вместо yourapp_client_sup:start_link(Socket, Options, ...)
этого . Убедитесь, что youreapp_client_connection:start_link_with_socket
функция запускает дочерний элемент через gen_server
proc_lib
функции или (требование supervisor
модуля) и что функция передает управление сокетом дочернему элементу, в gen_tcp:controlling_process
противном случае ребенок не сможет использовать сокет.
Альтернативный подход заключается в создании фиктивного yourapp_client_sup
процесса, на который yourclient_connection_handler
процессы могут ссылаться при запуске. yourapp_client_sup
Процесс будет существовать только для передачи EXIT
сообщений от своего родителя процессам обработчика соединений. Ему нужно будет перехватывать существующие и игнорировать все EXIT
сообщения, кроме сообщений от своего родителя. В целом я предпочитаю использовать simple_one_for_one
подход супервайзера.
Ответ №2:
Если вы ожидаете, что этих процессов будет много, было бы неплохо добавить руководителя под вашим главным руководителем, чтобы разделить ответственность (и, возможно, использовать simple_one_for_one
настройку, чтобы упростить ситуацию, возможно, даже проще, чем в вашем текущем случае).
Дело в том, что если вам нужно контролировать эти процессы, всегда приятно иметь руководителя. Если не имеет значения, преуспеют они или нет, то, возможно, он вам не понадобится. Но опять же, я всегда утверждаю, что это небрежное кодирование. 😉
Единственное, чего я бы не стал делать, — это добавлять их в существующее дерево, если только не очевидно, откуда они взялись, и их довольно мало.