Подтвердить что ты не робот

Является ли Sinatra многопоточным?

Является ли Sinatra многопоточным? Я читал еще раз, где эта "синатра многопоточна по умолчанию", что это значит?

Рассмотрим этот пример

get "/multithread" do
  t1 = Thread.new{
    puts "sleeping for 10 sec"
    sleep 10
    # Actually make a call to Third party API using HTTP NET or whatever.
  }
  t1.join
  "multi thread"
end

get "/dummy" do
  "dummy"
end

Если я получаю доступ к "/multithread" и "/dummy" впоследствии на другой вкладке или в браузере, тогда ничего не может быть подано (в этом случае в течение 10 секунд), пока запрос "/многопоточность" не будет завершен. В случае, если активность зависает, приложение перестает отвечать.

Как мы можем обойти это без появления другого экземпляра приложения?

4b9b3361

Ответ 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).

Ответ 2

Во время поиска по всему миру найден этот камень:

sinatra-synchrony

который может вам помочь, потому что он затрагивает вас.

Существует также эталонный тест, они сделали почти то же самое, что вы хотите (внешние вызовы).

Заключение: EventMachine - это ответ здесь!

Ответ 3

Мысль, которую я мог бы разработать для людей, которые сталкиваются с этим. Sinatra включает в себя этот небольшой фрагмент кода:

   server.threaded = settings.threaded if server.respond_to? :threaded=    

Sinatra определит, какой драгоценный камень вы установили для веб-сервера (он же, тонкий, puma, что угодно.), и если он реагирует на "threaded", он будет задан для потоковой передачи, если потребуется. Ухоженная.

Ответ 4

После внесения некоторых изменений в код я смог запустить приложение padrino/sinatra на mizuno , Первоначально я пытался запустить приложение Padrino на jRuby, но он был просто слишком неустойчивым, и я не исследовал, почему. Я столкнулся с авариями JVM при работе на jRuby. Я также просмотрел эту статью, которая заставляет меня думать, почему даже выбрать Ruby, если развертывание может быть чем угодно, но просто.

Есть ли обсуждение развертывания приложений в рубине? Или я могу создать новый поток:)

Ответ 5

В последнее время я попал в JRuby, и я очень удивлен, насколько просто переключиться с MRI на JRuby. Это в значительной степени связано с заменой нескольких драгоценных камней (в большинстве случаев).

Вы должны взглянуть на комбинацию JRuby и Trinidad (сервер приложений). Torquebox также кажется интересным решением "все-в-одном", он поставляется с гораздо большим количеством, чем просто сервером приложений.

Если вы хотите иметь сервер приложений, который поддерживает потоки, и вы знакомы с Mongrel, Thin, Unicorn и т.д., то Trinidad, вероятно, легче всего переносить, поскольку он практически идентичен с точки зрения пользователей. Любить его до сих пор!