是否应将客户处理流程添加到主管树中?

时间:2020-03-06 14:55:08  来源:igfitidea点击:

在Erlang中,我有一个进程管理器树,其中包含一个接受tcp / ip连接的进程。对于每个传入的连接,我都会产生一个新进程。是否应将此过程添加到主管树中?

问候,
史蒂夫

解决方案

如果我们期望这些过程很多,最好在主要主管下添加一名主管来分开职责(并且可以使用simple_one_for_one设置使事情更简单,甚至可能比当前情况更简单)。

关键是,如果我们需要控制这些流程,那么拥有主管总是很高兴的。如果它们是否成功无关紧要,那么我们可能不需要一个。但是话又说回来,我总是认为那是草率的编码。 ;-)

我唯一不会做的就是将它们添加到我们现有的树中,除非很明显它们来自何处并且数量很少。

是的,我们应该将这些过程添加到监管层次结构中,以使它们在停止应用程序时能够正确/正常关闭。 (否则,最终将导致泄漏连接失败,因为依赖它们的应用程序基础结构将被关闭)。

我们可以创建一个simple_one_for_one战略主管,例如yourapp_client_sup,其子规范为{{Id,{yourapp_client_connection,start_link_with_socket,[]},重新启动,关机,工人,临时}。这里的"临时"类型很重要,因为通常没有用于连接处理程序的有用的重新启动策略,我们无法连接到客户端来重新启动连接。这里的"临时"将使主管报告连接处理程序的退出,但忽略它。

然后执行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消息从其父进程传播到连接处理程序进程。它将需要陷阱存在,并忽略除其父级消息外的所有"退出"消息。总的来说,我更喜欢使用" simple_one_for_one"管理方法。