1

Sinatra アプリは、長時間実行されるタスクの要求を受け取り、それらを EM.defer して、EM の 20 スレッドの内部プールで起動します。20 を超える EM.defer が実行されている場合、それらは EM.defer によって EM のスレッドキューに格納されます。

ただし、それらを処理する EM スレッドが利用可能になるまで、Sinatra は要求を処理しないようです。私の質問は、シナトラはメインスレッドのリアクターを使用してすべてのリクエストを処理することを想定していませんか? 新しいリクエストを行うと、スレッドキューに追加が表示されるのはなぜですか?

再現する手順:

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
4

2 に答える 2

4

さて、Sinatra はデフォルトで Thin をスレッド モードで起動し、上記の動作を引き起こしているようです。あなたは付け加えられます

set :threaded, false

Sinatra の構成セクションでこれを行うと、Reactor が別のスレッドでリクエストを延期し、負荷がかかっているときにブロックするのを防ぐことができます。

ソース1

ソース2

于 2012-06-05T09:46:15.393 に答える
0

私があなたの質問について何か誤解していない限り、これはEventMachineがどのように機能するかとほぼ同じです。EM.deferのドキュメントを確認すると、次のように記載されています。

永久にブロックする遅延操作を記述しないでください。その場合、現在の実装では問題が検出されず、スレッドがプールに戻されることはありません。EventMachineはプール内のスレッドの数を制限するため、これを十分な回数実行すると、後続の遅延操作を実行する機会がなくなります。

基本的に、スレッドの数には限りがあり、それらを使い切ると、スレッドが使用可能になるまで保留中の操作はブロックされます。

より多くのスレッドが必要な場合は、バンプする可能性がありますがthreadpool_size、最終的にはそれは長期的な解決策ではありません。

Sinatraはマルチスレッドですか?シナトラとスレッドについてのSOに関する本当に良い質問です。要するに、Sinatraは素晴らしいですが、まともなスレッドが必要な場合は、他の場所を探す必要があるかもしれません。

于 2012-06-04T14:18:43.390 に答える