Да, вы должны добавить эти процессы в иерархию контроля, поскольку вы хотите, чтобы они были корректно / корректно завершены, когда ваше приложение остановлено. (В противном случае вы получите утечку соединений, которые будут выходить из строя, поскольку инфраструктура приложения зависит от того, было ли отключено).
Вы можете создать 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
.