Поскольку 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, без изменений.
Как правильно хранить данные для каждого запроса?
Почему существуют гемы (включая сам Rails и наклон), которые используют Thread.current для хранения? Как они преодолевают эту проблему?
Может быть, Thread.current безопасен для запроса, но просто не очищается после запроса, и мне нужно сделать это самому?
- Протестировано с Rails 3.2.9
Обновлять
Подводя итог приведенному ниже обсуждению с @skalee и @JesseWolgamott и моим выводам:
Thread.current зависит от сервера, на котором работает приложение. Хотя сервер может убедиться, что два запроса не выполняются одновременно в одном и том же Thread.current, значения в этом хэше могут не очищаться между запросами, поэтому в случае использования - должно быть установлено начальное значение. переопределить последнее значение.
Есть некоторые известные жемчужины, которые используют Thread.current, такие как Rails, Tilt и draper. Думаю, если бы это было запрещено или небезопасно, они бы им не пользовались. Также кажется, что все они устанавливают значение перед использованием любого ключа в хеше (и даже возвращают исходное значение после завершения запроса).
Но в целом Thread.current — не лучшая практика для хранения по запросу. В большинстве случаев подойдет лучший дизайн, но в некоторых случаях может помочь использование env
. Он доступен в контроллерах, а также в промежуточном программном обеспечении и может быть внедрен в любое место приложения.
Обновление 2. Похоже, что на данный момент draper неправильно использует Thread.current. См. https://github.com/drapergem/draper/issues/390.
Обновление 3: исправлена ошибка с драйпером.