Вопрос по ruby – Почему Sinatra запрос принимает EM поток?

1

Приложение Sinatra получает запросы на длительные задачи и откладывает их EM, запуская их во внутреннем пуле EM из 20 потоков. Когда запущено более 20 EM.defer, они сохраняются в очереди EM для EM.defer.

Однако кажется, что Sinatra не будет обслуживать любые запросы, пока не будет доступен поток EM для их обработки. Мой вопрос заключается в том, не предполагает ли Синатра использовать реактор основного потока для обслуживания всех запросов? Почему я вижу добавление в очереди тем, когда я делаю новый запрос?

Действия по воспроизведению:

Access /track/
Launch 30 /sleep/ reqs to fill the threadqueue
Access /ping/ and notice the add in the threadqueue as well as the delay

Код для воспроизведения:

require 'sinatra'
#monkeypatch EM so we can access threadpools
module EventMachine 
  def self.queuedDefers 
    @threadqueue==nil ? 0: @threadqueue.size 
  end
  def self.availThreads 
    @threadqueue==nil ? 0: @threadqueue.num_waiting
  end
  def self.busyThreads 
    @threadqueue==nil ? 0: @threadpool_size - @threadqueue.num_waiting
  end   
end 
get '/track/?' do
  EM.add_periodic_timer(1) do 
    p "Busy: " + EventMachine.busyThreads.to_s + "/" +EventMachine.threadpool_size.to_s + ", Available: " + EventMachine.availThreads.to_s + "/" +EventMachine.threadpool_size.to_s + ", Queued: " + EventMachine.queuedDefers.to_s 
  end 
end

get '/sleep/?' do
  EM.defer(Proc.new {sleep 20}, Proc.new {body "DONE"})
end

get '/ping/?' do
  body "pong"
end

Я попробовал то же самое на Rack / Thin (без Sinatra) и работает так, как он должен, поэтому я предполагаю, что Sinatra вызывает это.

Ruby version: 1.9.3.p125
EventMachine: 1.0.0.beta.4.1
Sinatra: 1.3.2
OS: Windows

Ваш Ответ

2   ответа
0

Если я не правильно понял что-то в вашем вопросе, то именно так работает EventMachine. Если вы проверитедокументы для EM.deferони заявляют:

Don't write a deferred operation that will block forever. If so, the current implementation will not detect the problem, and the thread will never be returned to the pool. EventMachine limits the number of threads in its pool, so if you do this enough times, your subsequent deferred operations won't get a chance to run.

По существу, имеется конечное число потоков, и если вы используете их, любые ожидающие операции будут блокироваться до тех пор, пока поток не станет доступным.

Возможно, удастсяthreadpool_size если вам просто нужно больше потоков, хотя в конечном итоге это не является долгосрочным решением.

Синатра многопоточная? это действительно хороший вопрос здесь о Sinatra и потоках. Короче говоря, Sinatra - это круто, но если вам нужны приличные потоки, вам, возможно, придется поискать что-то другое.

Error: User Rate Limit Exceeded gpavlidi
Error: User Rate Limit Exceeded
4

Итак, похоже, что Sinatra запускает Thin в поточном режиме по умолчанию, вызывая вышеуказанное поведение. Можете добавить

set :threaded, false

в разделе конфигурации Sinatra, и это предотвратит задержку запросов Reactor в отдельном потоке и блокировку при загрузке.

Source1

Source2

Error: User Rate Limit Exceeded

Похожие вопросы