1

セルロイドプールに対する私の理解は、ちょっと壊れていると思います. 以下で説明しようと思いますが、その前に簡単なメモを。

: 私たちのシステムはfast client、ZeroMQ を介して非常に通過するメッセージに対して実行されています。

以下のバニラセルロイドアプリで

class VanillaClient
   include Celluloid::ZMQ

   def read
      loop { async.evaluate_response(socket.read_multipart)
   end

   def evaluate_response(data)
      ## the reason for using defer can be found over here.

      Celluloid.defer do 
        ExternalService.execute(data)
      end
   end
end

私たちのシステムは、しばらくして、理由 'Can't spawn more thread'(またはそのようなもの)の後に失敗します

そのため、(上記の問題を回避するために) Celluloid Pool を使用して、生成されるスレッドの数を制限できるようにするつもりでした。

Celluloid Pool に対する私の理解は、Celluloid Pool は、タスクを並行して分散できるように、アクターのプールを維持するということです。

したがって、私はそれをテストすることにしましたが、私のテストケースによると、シリアルに動作するようです (つまり、物事が分散したり、並列に発生したりすることはありません)。

これを複製する例。

sender-1.rb

## Send message `1` to the the_client.rb

sender-2.rb

## Send message `2` to the the_client.rb

the_client.rb

## take message from sender-1 and sender-2 and return it back to receiver.rb
## heads on, the `sleep` is introduced to test/replicate the IO block that happens in the actual code.

receiver.rb

## print the message obtained from the_client.rb

によって送信されたデータを消費する前に、プールが 1 秒間ブロックされたように見えるsender-2.rb前に が実行された場合(スリープ時間は、ここで確認できます)。sender-1.rb20the_client.rbsender-1.rb

ruby-2.2.2 でも jRuby-9.0.5.0 でも同じように動作します。プールがそのような行動をとる原因として考えられるものは何ですか?

4

1 に答える 1

0

あなたのpool呼び出しは非同期ではありません。

evaluateonの実行は、元の例のように、プールを使用せずに静止@poolする必要があります。.async非同期動作も必要ですが、複数のハンドラー アクターも必要です。


次に、Pool.asyncバグに遭遇する可能性があります。

これは、プール内の少なくとも 1 つのアクタが終了するまで、プール5へのヒットが応答しなくなることを意味します。evaluate最悪のシナリオでは、6+リクエストを立て続けに受け取った場合、実行に数秒かかり、それから実行に数秒かかるため、数秒6thかかり120ます。5*2020


遅延の原因となっている実際の操作によっては、プールのサイズを後で調整する必要がある場合があります。

于 2016-03-12T03:21:34.440 に答える