2011-11-04 17 views
6

私たちはRailsとEventMachineを一緒に使用しています。そして、そのコンボをPassengerで使用する場合、非常に特別な設定が必要です。多くの試行錯誤の後、私はEventMachineの初期化をうまく行っていますが、コードを少し良く理解したいと思います。このコードスニペットの下でわかるように、イニシャライザはPassengerをチェックし、EventMachineを再起動する前にフォークされたプロセスかどうかを確認します。EventMachineスレッドとRubyスレッド - 実際に何が起こっていますか?

私の質問はEM.reactor_runningに関連していますか? EM.stopコマンドを使用します。 Passengerがプロセスをフォークした場合、新しいスレッドでEMリファレンスを再起動する必要があるのはなぜですか? EM.reactor_runningの場合?真を返します、私はどのEMインスタンスを参照していますか?

あなたがここに私たちのブログ上で完全な初期化コードを見ることができますhttp://www.hiringthing.com/2011/11/04/eventmachine-with-rails.html

答えて

13

まず第一に、関係なく、あなたがいつもとは無関係に、同じEMインスタンスを参照します何があるのRubyプロセスごとに1つだけEventMachineインスタンスはませんので、あなたの現在のスレッド

原子炉を新しい独立したスレッドで実行して、メインスレッド(その目的はウェブ要求を提供する)をブロックしないようにします。それ以外の場合、EM.runは制御を引き継ぎ、実行ループに入り、EM.runブロックから離れることはありません。 EM.reactor_running? EMループがどこかで動いている場合、真を返します。 Rubyプロセスごとに1つしかないので、メソッドがEMが実行中かどうかを判断するのは簡単です。

ここにある設定は、実行中の他のすべてのものに干渉することなく、通常のRubyプロセス内でEMを使用する最も簡単な方法です。私はあなたのWebアプリケーションからAMQPブローカにメッセージを送ると仮定しています。メッセージを送信するたびに、別のスレッドでEMの実行ループに入り、その部分はあなたにはかなり透過的で、メインループには影響せず、Rails Webリクエストの処理を継続できます。 EM.next_tickを使用して、常にEMループに物を押し込むように注意してください。 EMで開いたソケットを別のスレッドで処理しようとすると、問題が発生する可能性がありますが、これは発生時に発生したライブラリーを使用して作成しています)

新しいループを開始する前にEMループを停止する親プロセスから残っている可能性のあるEMループのうち、親プロセスでEMを使用して開いたファイル記述子に問題が生じる可能性があります。カスタムコードでは、これはEM.fork_reactorを使用することで回避できますが、親プロセスが制御できないため、新しいインスタンスを開始する前に原子炉が存在するかどうかを確認して停止するのが最も安全です。

+0

すばらしい説明ありがとうございます。私は自分のスレッドでEMを実行する必要性についてはっきりしていますが、「EMループが残っているかもしれません」と言うと、私は少し不明です。 EMループはどのように「残っている」でしょうか?私は親プロセスのEMをシャットダウンするつもりはありませんか? – Joshua

+0

これはまさにあなたがやっていることです。親プロセスから残っている可能性のあるEMをシャットダウンしています。 EMループが親プロセスで実行されると、それもforkされますが、通常、親から残されたファイル記述子にはまったく関心がありませんので、代わりにゼロから始めます。乗客がEMループを単独で走らせる可能性が低いことを考えると、これは何よりも安全対策のほうです。 – roidrage

+0

同様の状況で、Ruby-amqp gemを使ってRabbitMQを使って作業しています。 Thinは独自のEventMachineループを持っています。私は現在、EventMachine.next_tickを使用して、私のamqpを処理しています。これは正しいのですか、EventMachine.fork_reactorを使用してAMQPにEMを使用する必要がありますか? – wchrisjohnson

関連する問題