9

EventMachine でいくつかのジョブをバックグラウンド化する可能性を検討しています。Sinatra ではこれはうまく機能しているように見えますが、Rails 3 はビューをレンダリングする前にすべてのティックを実行しているようです。

シン Web サーバーで次のコードを実行すると、期待どおりに動作します。最初のリクエストはすぐに返され、2 番目のリクエストは 3 秒間のスリープ コールが終了するのを待っています。これは予期される動作です。

class EMSinatra < Sinatra::Base
  get "/" do
    EM.next_tick { sleep 3 }
    "Hello"
  end
end

一方、Rails 3の実行中は同じことをしようとしています:(シンの下で実行)

class EmController < ApplicationController
  def index
    EM.next_tick {
      sleep(3)
    }
  end
end

Rails では、ブラウザにビューをレンダリングする前に sleep 呼び出しが発生します。その結果、最初のページがレンダリングされるまで 3 秒間待機しています。

なぜこれが起こっているのか誰にも分かりますか?これが良い習慣であるかどうかについてのコメントは求めていません。私は単に実験しています。小さなタスクをリアクター ループに投入することは、興味深い調査のように思えます。ノンブロッキングの http リクエストを行う場合、なぜクライアントを待たなければならないのでしょうか?

4

2 に答える 2

3

これがあなたが探している答えであるかどうかはわかりませんが、私は以前にこれについていくつかの調査をしました。背景情報を少しお話ししましょう。私たちが達成したかったのは、コントローラーアクションの読み込みに時間がかかる場合でも、レールがテンプレートツリーの一部(レイアウトの最初の部分など)を既にフラッシュしていることです。これの効果は、Webサーバーがまだ作業を行っている間に、ユーザーがブラウザーに何かを既に表示していることです。もちろん、メインビューはおそらくコントローラーアクションからのデータを必要とするため、レンダリングを待つ必要があります。

この手法はBigPipeとも呼ばれ、Facebookはこれについて素晴らしいブログを書いています:http: //www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919

とにかく、rails 3でこれを達成するためにいくつかの調査を行った後、私はYehudaKatzによって作成されたこのブログ投稿を見つけました。 http://yehudakatz.com/2010/09/07/automatic-flushing-the-rails-3-1-plan/

だから今のところ、あなたは本当にコントローラーを待つことに固執する必要があると思います

于 2011-02-23T10:52:45.400 に答える
0

EM.next_tick の代わりに EM.defer を使用すると、応答が返された後にスリープが発生します。

于 2012-10-06T05:20:44.173 に答える