开发者

Collecting info about simple_one_for_one workers

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜