Я пытаюсь полностью понять возможности одновременной обработки запросов в Rack. Я использовал async_sinatra для создания приложения с длительным опросом, и сейчас я экспериментирую с голым железом Rack, используя throw: async
и / или флаг Thin --threaded. Мне нравится эта тема, но есть некоторые вещи, которые я просто не понимаю. (Нет, я не путаю параллелизм с параллелизмом, и да, я понимаю ограничения, налагаемые GIL.)
Q1. Мои тесты показывают, что thin --threaded
(т.е. rack.multithread = true
) запускает запросы одновременно в отдельных потоках (я предполагаю, что с использованием EM), то есть длительный запрос A не будет блокировать запрос B (IO в сторону). Это означает, что моему приложению не требуется никакого специального кодирования (например, обратных вызовов) для достижения параллелизма (опять же, игнорирование блокирующих вызовов БД, ввода-вывода и т. Д.). Это то, что, как мне кажется, я наблюдал - это правильно?
Q2. Существует еще один, более часто обсуждаемый способ достижения параллелизма, включающий EventMachine.defer
и throw: async
. Строго говоря, запросы не обрабатываются с помощью потоков. Они обрабатываются последовательно, но всю тяжелую работу и обратный вызов передают в EventMachine, который использует async.callback для отправки ответа в более позднее время. После того, как запрос A выгружает свою работу в EM.defer, запускается запрос B. Это правильно?
Q3. Если предположить, что вышеизложенное более или менее верно, есть ли какое-то конкретное преимущество у одного метода перед другим? Очевидно - многопоточный
выглядит как волшебная пуля. Есть ли минусы? Если нет, то почему все говорят об async_sinatra
/ throw: async
/ async.callback
? Возможно, первое звучит так: «Я хочу сделать мое приложение Rails более быстрым при большой нагрузке», а второе лучше подходит для приложений с большим количеством длительных запросов? Или, может быть, масштаб является фактором? Просто догадываюсь.
Я использую Thin 1.2.11 на MRI Ruby 1.9.2. (К вашему сведению, я должен использовать флаг - no-epoll
, так как существует давняя, предположительно решенная, но не совсем проблема с использованием EventMachine epoll и Ruby 1.9.2. Это не относится к делу, но любое понимание приветствуется.)