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!
は必要ないはずです(試しても違いはありません)。
この記事の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_concurrency
をtrue
またはfalse
に設定できます。 DEV環境では、次のようにする必要があります。config.cache_classes=false config.allow_concurrency=true
ステートメント:これは、config.cache_classes = false(デフォルトではdev envである)の場合、同時リクエストができないことを意味します。は正しくありません。
MRIとJRubyを使用して並行性をテストする実験を設定する この答え を参照できます。結果は驚くべきものです。 MRIはJRubyよりも高速でした。
MRI同時実行の実験は GitHub上 です。実験では同時リクエストのみをテストします。コントローラに競合状態はありません。ただし、コントローラーの競合状態をテストするために、上記の記事の例を実装することはそれほど難しくないと思います。
デフォルトでは、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
開発環境でキャッシュクラスを無効にして同時リクエストを行うことができるはずです。