Hi,
in Erlang I have a supervisor-tree of processes, containing one that accepts tcp/ip connections. For each incoming connection I spawn a new process. Should this process be added to the supervisor tree or not?
Regards, Steve
Hi,
in Erlang I have a supervisor-tree of processes, containing one that accepts tcp/ip connections. For each incoming connection I spawn a new process. Should this process be added to the supervisor tree or not?
Regards, Steve
If you expect these processes to be many, it could be a good idea to add a supervisor under your main supervisor as to separate responsibility (and maybe use the simple_one_for_one
setting to make things simpler, maybe even simpler than your current case).
The thing is, if you need to control these processes, it's always nice to have a supervisor. If it doesn't matter if they succeed or not, then you might not need one. But then again, I always argue that that is sloppy coding. ;-)
The only thing I wouldn't do, is to add them to your existing tree, unless it is very obvious where they come from and they're fairly few.
Yes, you should add these processes to the supervision heirarchy as you want them to be correctly/gracefully shutdown when your application is stopped. (Otherwise you end up leaking connections that will fail as the application infrastructure they depend on been shutdown).
You could create a simple_one_for_one
strategy supervisor say yourapp_client_sup
that has a child spec of {Id, {yourapp_client_connection, start_link_with_socket, []}, Restart, Shutdown, worker, temporary}
. The temporary
type here is important because there's normally no useful restart strategy for a connection handler - you can't connect out to the client to restart the connection. temporary
here will cause the supervisor to report the connection handler exit but otherwise ignore it.
The process that does gen_tcp:accept
will then create the connection handler process by doing supervisor:start_child(yourapp_client_sup, [Socket,Options,...])
rather than yourapp_client_sup:start_link(Socket, Options, ...)
. Ensure that the youreapp_client_connection:start_link_with_socket
function starts the child via gen_server
or proc_lib
functions (a requirement of the supervisor
module) and that the function transfers control of the socket to the child with gen_tcp:controlling_process
otherwise the child won't be able to use the socket.
An alternate approach is to create a dummy yourapp_client_sup
process that yourclient_connection_handler
processes can link to at startup. The yourapp_client_sup
process will just exist to propagate EXIT
messages from its parent to the connection handler processes. It will need to trap exists and ignore all EXIT
messages other than those from its parent. On the whole, I prefer to use the simple_one_for_one
supervisor approach.