如何跟踪erlang中的子进程?

如何跟踪erlang中的子进程?,erlang,child-process,erlang-supervisor,Erlang,Child Process,Erlang Supervisor,我有一个静态的“主机”列表及其信息,还有一个动态的“主机代理”列表。只要通过TCP连接连接到服务器,每个主机都只有一个代理。由于主机可能已连接,也可能未连接,其代理进程可能已启动,也可能未启动。当一个带有主机ID的TCP数据包到达时,我需要知道这个主机的“代理”是否启动了 连接负责从tcp套接字接收和发送数据,解析数据以确定它应该发送到哪个主机,并将数据传递给它的host agent进行处理 主机保存主机信息。Host agent处理传入数据,将主机信息保存到主机,并决定以何种格式发送内容(例如

我有一个静态的“主机”列表及其信息,还有一个动态的“主机代理”列表。只要通过TCP连接连接到服务器,每个主机都只有一个代理。由于主机可能已连接,也可能未连接,其代理进程可能已启动,也可能未启动。当一个带有主机ID的TCP数据包到达时,我需要知道这个主机的“代理”是否启动了

连接负责从tcp套接字接收和发送数据,解析数据以确定它应该发送到哪个主机,并将数据传递给它的host agent进行处理

主机保存主机信息。Host agent处理传入数据,将主机信息保存到主机,并决定以何种格式发送内容(例如,使用主机id和响应代码向客户端发送确认)

在数据包中,它指定了源主机和目标主机,这意味着它由源主机发送,并且应该由目标主机接收。在这种情况下,目标主机可以在另一个连接中连接。这就是为什么所有连接都需要一个全局映射,以方便获取目标主机代理pid

我有一个监控树,
host\u supervisor
监控所有
主机
connection\u supervisor
监控每个
连接
host\u agent\u supervisor
监控
代理
host\u supervisor
connection\u supervisor
都由应用程序监督员进行监督,这意味着它们是监督树中的一级子级。但是
host\u agent\u supervisor
处于
connection\u supervisor

问题:

  • 使用host_id和 主机\代理\ pid对
  • 如果1。是真的,如何更新主机\u代理\u pid 当出现问题并重新启动代理时
  • 有没有更好的办法来实施这个案例?我的解决方案似乎没有遵循“erlang方式”

  • 为了获得主管的子进程列表,可以使用API。它获取对主管的引用,可以是其注册名或PID,并返回其子级的列表

    supervisor:which_children(SupRef) -> [{Id, Child, Type, Modules}]
    

    您的问题的简单或快速答案如下:

  • 这很好,不过除了地图之外,你还可以使用gb_树、dict或ETS表(当然,地图是所有这些中最不成熟的)。然而,尽管如此,原则上,PID查找表的键/ID还是可以的。与其他进程相比,ETS可能会带来性能优势,因为您可以创建一个可以从其他进程访问的ETS表,从而消除了单个进程执行所有读写操作的必要性。这可能重要,也可能不合适

  • 一种简单的方法是,每次“host agent”启动时,它都会生成另一个进程,该进程只会链接到“host agent”,并在“host agent”死亡时从任何存储中删除host ID到agent PID的映射。另一种方法是使映射存储进程本身链接到您的host agent PID,这可能会减少您对可能的争用条件的关注

  • 可能吧。当我阅读您的问题时,我留下了一些问题,并且普遍认为我选择的解决方案不会导致我找到您所询问的精确查找问题(即,在收到TCP数据包时查找“host agent”的PID),但我不能确定这不是因为您已经努力将堆栈溢出问题最小化。我有点不清楚您的“主机”、“主机代理”和“连接”流程的角色、职责和交互到底是什么,以及它们是否都应该存在和/或有单独的监督树

  • 所以,看看可能的替代方案。。。当您说“当TCP数据包到达”时,我假设您的意思是当一个外部主机连接到一个侦听套接字或在一个已被接受的现有套接字上发送一些数据时,并且主机ID是主机名(和或端口)或外部主机在连接后发送给您的其他任意ID

    不管怎样。。。一般来说,在这种情况下,我希望会产生一个新的进程(在您的案例中是“host agent”)来处理新建立的TCP连接(通过一个动态(例如简单的一对一)管理器),获得作为该连接的服务器端端点的套接字的所有权;根据需要读取和写入套接字,并在连接关闭时终止

    在该模型中,如果已经存在连接,则应始终启动“host agent”,如果没有连接,则始终不启动“host agent”,并且任何传入的TCP数据包将自动落入正确的代理手中,因为它将被传递到代理正在处理的套接字,或者如果是新连接,代理将被启动

    现在不再需要在收到TCP数据包时查找代理的PID

    如果您出于其他原因需要查找代理的PID,比如说您的服务器有时需要主动向可能连接的“主机”发送数据,那么您必须获取所有受监管的“主机代理”的列表,并选择正确的一个(根据Hamidreza的回答,为此您将使用supervisor:which_children/1)或者,您可以使用map、gb_树、dict、ets等来维护主机ID到PID的映射。这取决于您可能拥有的“主机”的数量——如果超过少数,那么您应该维护某种映射,以便查找时间不会太长

    最后的评论,如果你还没有考虑过的话,你可以考虑看<代码> GPRC < /C>。它做这种事情

    编辑/添加(以下问题编辑):

    你的连接过程对我来说是多余的;如上所述,如果您将套接字提供给host agent,那么大部分责任都是
            top_sup
               |
         .------------------------------.
         |             |                |
    map_server    svc_listener      hosts_sup (simple one to one)
                                        |
                            .----------------------------->
                            |    |    |    |   |    |