2011-06-27 10 views
2

私は、たくさんのof_one_for_oneワーカーを開始する上司(aliceと呼ばれています)を持っています。今、私はすべての作品について一緒に情報を得たいと思っています。たとえば、ワーカーがTCPサーバーであり、ワーカーが使用するすべてのポート番号、またはそれらのワーカーに接続されているすべてのリモートアドレスを取得したいとします。この機能はどこに置くべきですか?simple_one_for_one workersについての情報を収集します。

Supervisorにはgen_server機能がなく、コールに応答できません。だから、私にとっては、最も妥当な方法は、スーパーバイザーのアリスを生み出す別のスーパーバイザー(ボブと呼ぶ)とスーパーバイザーを呼び出すことによって{get、ports_used_by_alices_workers}のようなコールを実装する別のgen_server(charile)を持つことです:which_children(alice)それはそれぞれのアリスの子供のためのポートです。だからチャーリーはアリスの兄弟で、アリスの子供たちに電話をかけます。それは大丈夫ですか?あるいはこれを行うためのよりエレガントな方法がありますか?

答えて

3

この情報を収集するために別のプロセスは必要ありません。ポート情報が自分自身で収集されるようにするには、supervisor:which_children/1の子のリストを取得してから各子に問い合わせます。これを行うAPI関数を提供しますが、その関数を呼び出し元のプロセスで実行させます。

代わりに、あなたが文書化されていない(と保証排尿)ルートを行く、とのすべての子供たちと話をすることなく、必要な情報を取得するためのerlangの根性でつつくことができます:

[{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)] 
] 

あなたが得ることができます情報源の情報であるinet:i/0の情報です。

+0

ありがとう、監督:which_children/1は私が必要としていたものです。 – dijxtra

+0

文書化されていないことを行うことは、おそらくかなり悪いアドバイスです。私はあなたの答えからそれを削除します。 –

関連する問題