Если ваш ответ в Sinatra возвращает «каждый» объект, цикл обработки событий Sinatra будет «каждый» ваш результат и выдаст результаты в потоковом режиме как HTTP-ответ.Однако, если есть параллельные запросы к Sinatra, он будет перебирать все элементы одного ответа перед обработкой другого запроса.Если у нас есть курсор к результатам какого-либо запроса к БД, это означает, что нам нужно подождать, пока все данные будут доступны, прежде чем обрабатывать параллельный запрос.
Я посмотрел на гем async-sinatra и http://macournoyer.com/blog/2009/06/04/pusher-and-async-with-thin/, думал, что это решит мою проблему, но я попробовал этот пример:
require 'sinatra/async'
class AsyncTest < Sinatra::Base
register Sinatra::Async
aget '/' do
body "hello async"
end
aget '/delay/:n' do |n|
EM.add_timer(n.to_i) { body { "delayed for #{n} seconds" } }
end
end
и запрос /delay/5
не работает одновременно, как я ожидаю, то есть я делаю3 запроса одновременно, и отладчик Chrome отмечает время ответа примерно 5, 10 и 15 секунд.
Я пропустил некоторые настройки или есть другой способ сообщить Sinatra / Thin для одновременной обработки запросов?
Обновление: Вот еще один ключ в этом (или, возможно, проясняет ситуацию): Запуск curl -i <a href="http://localhost:3000/delay/5" rel="nofollow">http://localhost:3000/delay/5</a>
одновременно ведет к правильному поведению (2 запроса каждый возвращается через ~ 5 секунд).Запуск ab -c 10 -n 50 <a href="http://locahost:3000/delay/5" rel="nofollow">http://locahost:3000/delay/5</a>
(утилита тестирования Apache) также возвращает что-то разумное для общего времени (~ 25 секунд).Firefox демонстрирует то же поведение, что и Chrome.Чем браузеры отличаются от утилит командной строки?