Thin/Unicorn はシングル スレッドであるため、Thread.current/per-request ストレージをどのように処理しますか?
簡単なテストを実行しただけです-あるセッションでキーを設定し、別のセッションから読み取ります-常に同じ場所から書き込み/読み取りを行うように見えます。ただし、WEBrickでは発生しません。
class TestController < ApplicationController
def get
render text: Thread.current[:xxx].inspect
end
def set
Thread.current[:xxx] = 1
render text: "SET to #{Thread.current[:xxx]}"
end
end
config.threadsafe!
application.rbに追加してみましたが、変化なし。
リクエストごとのデータを保存する正しい方法は何ですか?
ストレージに Thread.current を使用する gem (Rails 自体、tilt を含む) があるのはなぜですか? 彼らはこの問題をどのように克服しますか?
Thread.currentはリクエストごとに安全である可能性がありますが、リクエスト後にクリアされず、自分でそれを行う必要がありますか?
- Rails 3.2.9 でテスト済み
アップデート
以下の@skaleeと@JesseWolgamottとの議論と私の調査結果を要約すると--
Thread.current は、アプリが実行されているサーバーによって異なります。サーバーは同じ Thread.current で 2 つのリクエストが同時に実行されないようにする場合がありますが、このハッシュの値はリクエスト間でクリアされない可能性があるため、使用する場合は、最後の値を上書きするように初期値を設定する必要があります。
Rails、tilt、draper など、Thread.current を使用する有名な gem がいくつかあります。禁止されていたり、安全でない場合、彼らはそれを使用しないと思います。また、ハッシュでキーを使用する前にすべての値を設定しているようです (さらに、リクエストが終了した後に元の値に戻します)。
しかし全体として、Thread.current はリクエストごとのストレージのベスト プラクティスではありません。ほとんどの場合、より良い設計で十分ですが、場合によっては を使用すると効果的env
です。コントローラーだけでなく、ミドルウェアでも利用でき、アプリ内の任意の場所に注入できます。
更新 2 - 今のところ、draper は Thread.current を間違って使用しているようです。https://github.com/drapergem/draper/issues/390を参照してください。
Update 3 - ドレーパーのバグが修正されました。