Collecting info about simple

I have a supervisor (called alice) which starts a bunch of_one_for_one workers. Now I'd like to get some info about all of the works together. For instance, let's say workers are TCP servers and I'd like to get all port numbers used by workers, or all remote addresses which are connected to those workers. Where should I put this functionality?

Supervisor doesn't have gen_server functionality and cannot answer calls. So, it seems to me, the most reasonable way is to have another supervisor (called bob) which spawns supervisor alice and another gen_server (charile) which implements calls like {get, ports_used_by_alices_workers} by calling supervisor:which_children(alice) and then asking each alice's child for it's port. So, charile is alice's sibling and answers calls about alice's children. Is that OK? Or is there a more elegant way of doing this?


You don't need a separate process to collect this information - you can just let whoever wants the port information collect it themselves by getting the list of children with supervisor:which_children/1 and then querying each child. Provide an API function that does this, but let that function run in the caller's process.

Alternately, you could go the undocumented (and warranty voiding) route, and poke around in the guts of erlang to get the information you want without talking to the children at all:

[{Child, 
  %% Query linked port for socket information
  [{Link, prim_inet:sockname(Link),
          prim_inet:peername(Link)}
    || %% get list of linked process and ports for process 'Child'
       Link <- element(2, process_info(Child, links)),
       %% filter down to linked ports.
       is_port(Link)] 
  }
 %% Map over all children of the supervisor 'Sup'.
 || Child <- [Pid || {_,Pid,_,_} = supervisor:which_children(Sup)] 
 ]

You can get an idea of the information available in the source for inet:i/0.

链接地址: http://www.djcxy.com/p/38256.html

上一篇: Erlang管理员可以监控并重新启动C

下一篇: 收集关于简单的信息