2012-12-25 16 views
20

テストの準備:、 2番目の要求が実行されている:アクション複数のリクエストを同時に解決する方法はありますか?

の検索結果を訪問するブラウザで オープンつのタブ:アクション

テストに sleep 10最初のリクエストが完了し、ビューのレンダリングが開始されましたが、ビューはまだ空白です。 2番目の要求も終了した後、2つの要求が同時にビューのレンダリングを終了しました。

結論: Railsは単なる単一インスタンスです。 1つの要求は、前の要求が完了した後でのみアクションを入力できます。しかし、どのように応答部分を説明する?マルチリクエストが同時にビューをレンダリングするのはなぜですか?

答えて

4

WEBrickサーバーを使用していますか?これは、サーバーがシングルスレッドサーバーであり、(ワーカースレッドが1つであるため)一度に1つの要求を満たすことができるためです。複数のリクエストの場合、リクエストのアクション部分を実行し、ビューレンダラを実行する前に、リクエストがあるかどうかを確認します。 10個のリクエストが並んでいる場合は、まず実際にビューをレンダリングする前にすべてのリクエストを完了します。これらの要求がすべて完了すると、ビューは順次レンダリングされます。

マルチスレッド環境が必要な場合は、PassengerまたはUnicornサーバーに切り替えることができます。

希望は意味があります。

+0

おかげで、あなたは私はあまり混乱して作ります。私は同時に多くのリクエストをテストしますが、10個以下のリクエストが並んだら、webrickはビューをレンダリングし、他のリクエストを解決します。 –

+0

私はwebrickがシングルスレッドサーバではないと思うので、 'config.threadsafe!'を設定することができます。 production.rbでは、複数のリクエストを同時に解決します。 –

+0

'config.threadsafe!'は自動的にWEBrickをマルチスレッドにしません。詳細は私の答えを見てください。 – Nowaker

19

WEBrickはマルチスレッドですが、Rails開発者はミューテックスをハードコーディングしているため、一度に1つの要求しか処理できません。 monkey-patch Rails::Serverを実行すると、マルチスレッドWEBrickを自由に実行できます。

コンフィグconfig.cache_classes = trueconfig.eager_load = trueの場合、WEBrickはマルチスレッド化されますが、これは通常RAILS_ENV=productionです。これは、開発時のクラスのリロードがスレッドセーフではないためです。 WEBrickには完全にRailsの4.0でマルチスレッド得るために

、ちょうどconfig/initializers/multithreaded_webrick.rbにこれを追加します。

# Remove Rack::Lock so WEBrick can be fully multi-threaded. 
require 'rails/commands/server' 

class Rails::Server 
    def middleware 
    middlewares = [] 
    middlewares << [Rails::Rack::Debugger] if options[:debugger] 
    middlewares << [::Rack::ContentLength] 

    Hash.new middlewares 
    end 
end 

我々は処分したrails/commands/server.rbで問題のコードは次のとおりです。

# FIXME: add Rack::Lock in the case people are using webrick. 
# This is to remain backwards compatible for those who are 
# running webrick in production. We should consider removing this 
# in development. 
if server.name == 'Rack::Handler::WEBrick' 
    middlewares << [::Rack::Lock] 
end 

それは必要ないですon Rails 4.2。同時並行して使用できます。あなたのenvセットアップの設定/環境/ development.rb(または設定/ application.rbで)下

+0

追加されましたが、ミドルウェアに 'Rack :: Lock'を追加しました – geekazoid

+1

@geekazoid、Rails 4.1私は仮定しますか?私はそれをRails 4.0でのみテストしました。私は4.1でそれを行う方法を見ていきます。 – Nowaker

+0

'config.allow_concurrency = true'を追加して解決しますか? – geekazoid

0

は、この行を追加します。

#Enable threaded mode 
    config.threadsafe! 
+1

このオプションはもはや必要/サポートされなくなりました(少なくともRails 4以降)。詳細については、http://tenderlovemaking.com/2012/06/18/removing-config-threadsafe.htmlを参照してください。 – ToniTornado

関連する問題