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