tl; dr Sinatra хорошо работает с потоками, но вам, вероятно, придется использовать другой веб-сервер.
Сам Синатра не навязывает какую-либо модель параллелизма, он даже не обрабатывает параллелизм. Это делается обработчиком Rack (веб-сервером), таким как Thin, WEBrick или Passenger. Сам Sinatra является поточно-ориентированным, что означает, что если ваш обработчик Rack использует несколько потоков для запросов к серверу, он работает просто отлично. Однако, поскольку Ruby 1.8 поддерживает только зеленые потоки, а Ruby 1.9 имеет глобальную блокировку виртуальной машины, потоки не так широко используются для параллелизма, так как в обеих версиях потоки не будут работать действительно параллельно. Однако завещание будет на JRuby или на предстоящем Rubinius 2.0 (обе альтернативные реализации Ruby).
Большинство существующих обработчиков Rack, использующих потоки, будут использовать пул потоков для повторного использования потоков вместо того, чтобы фактически создавать поток для каждого входящего запроса, поскольку создание потоков не является бесплатным, особенно на 1.9, где потоки отображают 1: 1 на собственные потоки. Зеленые потоки имеют гораздо меньше накладных расходов, поэтому волокна, которые в основном представляют собой совместно запланированные зеленые потоки, используемые в вышеупомянутой синатра-синхронии, стали так популярны в последнее время. Вы должны знать, что любое сетевое взаимодействие должно проходить через EventMachine, поэтому вы не можете использовать гем mysql
, например, для общения с вашей базой данных.
Волокна хорошо масштабируются для интенсивной обработки в сети, но с треском проваливаются при тяжелых вычислениях. У вас меньше шансов столкнуться с условиями гонки, что является распространенной ошибкой при параллельности, если вы используете волокна, поскольку они выполняют переключение контекста только в четко определенных точках (с синхронизацией, когда вы ожидаете ввода-вывода). Существует третья распространенная модель параллелизма: процессы. Вы можете использовать сервер preforking или запустить несколько процессов самостоятельно. Хотя на первый взгляд это кажется плохой идеей, у нее есть некоторые преимущества: в обычной реализации Ruby это единственный способ одновременного использования всех ваших процессоров. И вы избегаете общего состояния, поэтому нет расы по определению. Кроме того, многопроцессорные приложения легко масштабируются на нескольких машинах. Помните, что вы можете комбинировать несколько процессов с другими моделями параллелизма (четными, кооперативными, упреждающими).
Выбор в основном делается на используемом вами сервере и промежуточном программном обеспечении:
- Мультипроцесс, без предварительной обработки: Mongrel, Thin, WEBrick, Zbatery
- Мультипроцесс, предварительная обработка: Единорог, Радуга, Пассажир
- Evented (подходит для синатра-синхронии): Тонкий, Радуга, Збатери
- Резьбовые: Net :: HTTP :: Server, Резьбовые монгрелы, Puma, Rainbows, Zbatery, Thin [1], Phusion Passenger Enterprise> = 4
[1] начиная с Sinatra 1.3.0, Thin будет запускаться в многопоточном режиме, если он запускается с помощью Sinatra (то есть с ruby app.rb
, но не с командой thin
или с rackup
).