是否应该将客户端处理过程添加到主管树中?
Posted
技术标签:
【中文标题】是否应该将客户端处理过程添加到主管树中?【英文标题】:Should a client handling process be added to the supervisor tree? 【发布时间】:2010-09-14 05:50:02 【问题描述】:在 Erlang 中,我有一个进程主管树,其中包含一个接受 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
设置使事情变得更简单,甚至可能比您当前的更简单案例)。
问题是,如果您需要控制这些流程,最好有一个主管。如果他们成功与否无关紧要,那么您可能不需要一个。但话又说回来,我总是认为那是草率的编码。 ;-)
我不会做的唯一一件事就是将它们添加到您现有的树中,除非它们的来源非常明显并且它们很少。
【讨论】:
以上是关于是否应该将客户端处理过程添加到主管树中?的主要内容,如果未能解决你的问题,请参考以下文章