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