web-dev-qa-db-ja.com

Rails 4)と同時にリクエストを処理するにはどうすればよいですか?

Rails 4、config.threadsafe!およびPuma in Rails 3。

このコントローラがあるとしましょう

class ConcurrentController < ApplicationController
  def index
    sleep 10000
  end

  def show
  end
end

以前は、プーマをpuma -t 2:16 -p 3000(最小2スレッドの場合)で開始し、indexを押し、次にshowを押しても、showを適切にレンダリングできました。

Rails 4で、同じことを行おうとすると、Pumaがindexリクエストをロックし、showがレンダリングされないようになります。Ctrl-Cをサーバープーマは私にこのエラーを与えます:

Rack app error: #<ThreadError: Attempt to unlock a mutex which is locked by another thread>

Rails 4?config.threadsafe!は必要ないはずです(試しても違いはありません)。

33
Fredrik

この記事のconfig.threadsafe!の設定オプションについてお読みください config.threadsafe! を削除すると、config.threadsafe!のオプションを理解しやすくなり、特に並行性。

Rails 4 config.threadsafe!がデフォルトで設定されています。


今答えに

Railsでは、デフォルトで4つのリクエストがDEV環境のRack :: Lockミドルウェアによってミューテックスにラップされます。

同時実行を有効にするにする場合は、config.allow_concurrency=trueを設定できます。これにより、Rack :: Lockミドルウェアが無効になります。あなたの質問の別の回答で述べられているように、私はそれを削除しません。それは私にとってハックのように見えます。

config.cache_classes=trueがある場合、config.allow_concurrency(Rack :: Lockリクエストミューテックス)への割り当ては有効にならず、デフォルトで同時リクエストが許可されます。 config.cache_classes=falseがある場合は、config.allow_concurrencytrueまたはfalseに設定できます。 DEV環境では、次のようにする必要があります。

config.cache_classes=false
config.allow_concurrency=true

ステートメント:これは、config.cache_classes = false(デフォルトではdev envである)の場合、同時リクエストができないことを意味します。は正しくありません。

付録

MRIとJRubyを使用して並行性をテストする実験を設定する この答え を参照できます。結果は驚くべきものです。 MRIはJRubyよりも高速でした。

MRI同時実行の実験は GitHub上 です。実験では同時リクエストのみをテストします。コントローラに競合状態はありません。ただし、コントローラーの競合状態をテストするために、上記の記事の例を実装することはそれほど難しくないと思います。

36
Ely

デフォルトでは、Rails 4では、同時要求は開発環境で有効になっていません。

documentation でこの引用を見つけました。

Rack :: Lockはアプリをミューテックスでラップするため、一度に1つのスレッドのみが呼び出すことができます。 config.cache_classesがfalseの場合にのみ有効になります。

つまり、config.cache_classes = false(これはdev envではデフォルトです)同時リクエストはできません。

同時リクエストは、本番環境のサンプルで機能します。

1つの解決策は、config.cache_classes = true開発環境では、コードは変更時にリロードされません。これは実際には開発では機能しません。

2番目の種類のハッキングソリューションは、Rack::Lockミドルウェアを開発中。

だからあなたがdevelopment.rb次の行:

config.middleware.delete Rack::Lock

開発環境でキャッシュクラスを無効にして同時リクエストを行うことができるはずです。

21
Fredrik