2011-07-12 3 views
1

5つのライブTelnet、SSH、およびサーバーへのさまざまな接続を開き、相手側のJSONRPC呼び出しをリッスンするサーバープログラムを作成する必要があります。AnyEventのマスターワーカーサーバー

私は、開口部に問題をしたんや5つの接続を維持し、要求をリスニング:

# workers: 
open_myconnections(1..5); 
my $w1 = AnyEvent->timer (interval => $seconds, cb => sub { keep_conn_alive(1) }); 
my $w2 = AnyEvent->timer (interval => $seconds, cb => sub { keep_conn_alive(2) }); 
... 

# now listen for requests 
use AnyEvent::JSONRPC::Lite; 
# master: 
my $server = jsonrpc_server '127.0.0.1', '4423'; 
$server->reg_cb(
    queue_up => sub { 
     my ($res_cv, @params) = @_; 
     my $res = send_params_to_connection_queue(@params); 
     $res_cv->result($res); 
    }, 
); 

をしかし、今、私は立ち往生、すなわち最良の方法(非ブロックを把握しようとしています、AnyEventウェイ)私の機能send_params_to_connection_queue()は何をしている5人の労働者の間でキューを配布する。

これは非常に小さなサーバーことになっていると、他の賢明な選択肢が存在しない場合を除き、私は合格しますので、私はPOEを使用しないようにしようとしているが、任意のモジュールの提案は、高く評価されています。

+0

この場合、正確な配信が何を意味するのかよく分かりませんが、詳細を教えてください。 – MkV

+0

私は、利用可能な5人の労働者のうちの1人に着信要求を割り当てることを意味します。 – ojosilva

答えて

3

YAPC :: NA 2011では、ZeroMQと呼ばれる非常に優れたキューイングシステムについて学びました。 PerlバインディングはDirect Perl BindingsAnyEvent bindingsです。

 

               |----- ssh worker 
JSONRPC-Listener-EventLoop---->QueueingSystem---|----- telnet worker 
               |----- etc. 
+1

AnyMQとAnyEvent :: MPもあります(後者は、複数のプロセス/ノードがある場合にのみ興味があります) – MkV

+1

AnyEvent :: MPは素晴らしいです!私はおそらくそれを使用します。しかし、私の問題は、Net :: OpenSSHとTelnetがライブラリをブロックしているため、イベントキューを使用するのが難しいことです。 – ojosilva

+0

ブロッキングサービス(telnetなど)によって処理が実行されるノンブロッキングメインイベントループを使用します。メインループは、コールバック関数を設定して、キューウォーカーがブロッキングそれはコールバックを実行するメインループにシグナルを返すことができ、一般にデータを後処理し、パックをイベント要求者に送る。私は上記の返事で絵を描きました。 –

2

あなただけが「ベスト」は何か知っているが、そこにこれを行う方法の一般的なパターンがあり、多分それはあなたの本当の問題です。

基本的に、あなたはまだ送信されていないすべての要求格納するキュー、たとえば、配列、必要があります。

私@queueを。その後、

、あなたがリクエストをしたいたび、あなたは最初の「スケジューラ」機能キューにデータをプッシュし、次に呼び出し:

サブdo_req { を私の($データは、$ CB)= @ _; push @queue、[$ data、$ cb]; スケジューラ; }

スケジュール機能の目的は、作業者を選択し、 次の要求をオフ発射することである。

サブスケジューラ{ @queueまたは返します。これは何空のキュー

for my $worker (@workers) { 
    if ("$worker is free") { 
     my ($data, $cb) = @{ shift @queue }; 
     $worker->doit (sub { 
      &scheduler; 
      $cb->(@_); # call original callback 
     }); 
     return; 
    } 
    } 

}

を行うには#の何も自由労働者、それに要求を送信(「のdoIt」)、そしてそれが終わっています を見つけることではありません、それはスケジューラを呼び出し、再び。

従業員が「無料」かどうかはどのように決定するかはあなた次第です。たとえば、 は、未処理の要求が最も少ないワーカーを常に選択できます。 また、未処理のリクエストが5件未満のワーカーを選択することもできます。 またはいずれかの方法が最適です。

重要なことは、ワーカーがフリーになったとき(ジョブ が完了したため)、スケジューラを再度呼び出して、次のジョブをキューに入れることです。

このようにすれば、必要なジョブについては を忘れずに、労働者に任意の制限を課すことができますが、この制限によって送信できませんでした。

あり、この技術には多くのvariatinsがありますが、基本的な考え方は、常に同じ です:最初のキューのもの、そしてその後、キューを配布する必要のある、あなたは キューイング後、ジョブが完了した後、両方の呼び出し機能を持っています

リクエストを送信する必要がある場合、新しいジョブ/リクエストが作成/キューに登録されたとき、および未完了の ジョブが完了したときに、2つのイベントが発生します。

関連する問題