Как я могу выполнять запросы одновременно с Rails 4?
Я пытаюсь выполнить несколько запросов одновременно в Rails 4, что я смог сделать очень легко с config.threadsafe!
и Puma
в Rails 3.
Скажем, у меня этот контроллер
class ConcurrentController < ApplicationController
def index
sleep 10000
end
def show
end
end
Раньше я только начинал puma с puma -t 2:16 -p 3000
(для мин. 2 потока) и нажимал index
, а затем show
и по-прежнему имел show
рендеринг правильно.
В Rails 4, если я попытаюсь сделать то же самое, Puma теперь блокирует запрос index
, а show
никогда не будет отображаться. Когда я ударил Ctrl-C
для сервера Puma, я получаю эту ошибку:
Rack app error: #<ThreadError: Attempt to unlock a mutex which is locked by another thread>
Что мне не хватает, чтобы получить concurrency для работы с Rails 4? config.threadsafe!
не требуется (и не имеет значения, даже если я пытаюсь)
Ответы
Ответ 1
Я предлагаю вам ознакомиться с параметрами конфигурации config.threadsafe!
в этой статье Удаление config.threadsafe!
Это поможет вам лучше понять варианты config.threadsafe!
, в частности, разрешить concurrency.
В Rails 4 config.threadsafe!
устанавливается по умолчанию.
Теперь к ответу
В Rails 4 запросов по умолчанию обернуты Mutex промежуточным программным обеспечением Rack:: Lock в средах DEV.
Если вы хотите включить concurrency, вы можете установить 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), мы не можем Запросы. неверно.
Приложение
Вы можете обратиться к этому ответу, который устанавливает экспериментальное тестирование concurrency с использованием MRI и JRuby. Результаты удивляют. МРТ была быстрее, чем у JRuby.
Эксперимент с MRI concurrency на GitHub.
Эксперимент проверяет только одновременный запрос. В контроллере нет условий гонки. Однако, я думаю, что не слишком сложно реализовать пример из вышеприведенной статьи, чтобы проверить условия гонки в контроллере.
Ответ 2
Похоже, что по умолчанию в Rails 4 параллельные запросы не включены в среде разработки.
Я нашел эту цитату в документации .
Rack:: Lock обертывает приложение в мьютексе, поэтому его можно вызывать только по одному потоку за раз. Включается только тогда, когда config.cache_classes является ложным.
Это означает, что если config.cache_classes = false
(который по умолчанию находится в dev env), мы не можем иметь одновременные запросы.
Параллельные запросы работают с моим примером в рабочей среде.
Одним из решений является установка config.cache_classes = true
в среде разработки, но тогда код не перезагружается при изменении, что на самом деле не работает для разработки.
Второй вид хакерского решения - отключить промежуточное ПО Rack::Lock
в разработке.
Итак, если вы добавили в development.rb
следующую строку:
config.middleware.delete Rack::Lock
вы должны иметь возможность одновременных запросов в среде разработки с отключенными классами кэша.
Ответ 3
вы можете попробовать единорог, это очень просто в режиме разработки:
http://dave.is/unicorn.html