シナトラはマルチスレッドですか? 「シナトラはデフォルトでマルチスレッド化されている」という他の記事を読みましたが、それはどういう意味ですか?
この例を考えてみましょう
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」にアクセスすると、「/ multithread」リクエストが完了するまで、何も(この場合は10秒間)何も処理されません。アクティビティがフリーズした場合、アプリケーションが応答しなくなります。
アプリケーションの別のインスタンスを生成せずにこれを回避するにはどうすればよいですか?
tl; drシナトラはスレッドでうまく機能しますが、おそらく別のWebサーバーを使用する必要があります。
Sinatra自体は並行性モデルを強制せず、並行性も処理しません。これは、Thin、WEBrick、Passengerなどのラックハンドラー(Webサーバー)によって行われます。 Sinatra自体はスレッドセーフです。つまり、Rackハンドラーがサーバーリクエストに複数のスレッドを使用する場合、それは問題なく機能します。ただし、Ruby 1.8はグリーンスレッドのみをサポートし、Ruby 1.9はグローバルVMロックを持っているため、スレッドはそれほど広くありません。同時実行に使用されます。これは、両方のバージョンでスレッドが完全に並列に実行されるわけではないためですが、JRubyまたは今後のRubinius 2.0(両方の代替Ruby実装))では実行されます。
スレッドの作成は無料ではないため、着信リクエストごとに実際にスレッドを作成する代わりに、スレッドを使用する既存のほとんどのラックハンドラーはスレッドプールを使用してスレッドを再利用します。 1.9では、スレッドは1:1でネイティブスレッドにマッピングされます。グリーンスレッドはオーバーヘッドがはるかに少ないため、上記のシナトラ同期で使用される、基本的に協調的にスケジュールされたグリーンスレッドであるファイバーが最近非常に一般的になりました。ネットワーク通信はすべてEventMachineを経由する必要があるため、たとえばmysql
gemを使用してデータベースと通信することはできないことに注意してください。
ファイバーは、ネットワークの集中的な処理には適切にスケーリングしますが、大量の計算には失敗します。ファイバーを使用すると、明確に定義されたポイントでのみコンテキストスイッチが実行されるため(IOを待機するたびに同期が行われるため)、競合状態に陥る可能性が低くなります。 3つ目の一般的な同時実行モデルとして、プロセスがあります。プリフォークサーバーを使用するか、複数のプロセスを自分で起動できます。これは一見悪い考えのように見えますが、いくつかの利点があります。通常のRuby実装では、これはすべてのCPUを同時に使用する唯一の方法です。共有状態を避けるため、また、マルチプロセスアプリは複数のマシンで簡単にスケーリングできます。複数のプロセスを他の同時実行モデル(イベント、協調、プリエンプティブ)と組み合わせることができることに注意してください。
選択は主に、使用するサーバーとミドルウェアによって行われます。
[1] Sinatra 1.3.0以降、Sinatraによって起動された場合、Thinはスレッドモードで起動されます(つまり、Ruby app.rb
、ただしthin
コマンドやrackup
は使用できません)。
ぐるぐる回っているときに、この宝石を見つけました:
それはあなたの質問に触れるので、あなたを助けるかもしれません。
ベンチマークもあり、彼らはあなたが望むようにほとんど同じことをしました(外部呼び出し)。
結論:EventMachineがここでの答えです!
これに出くわした人のために詳しく説明すると思います。シナトラには、次の小さなコードが含まれています。
server.threaded = settings.threaded if server.respond_to? :threaded=
Sinatraは、Webサーバーにインストールしたgem(別名、thin、pumaなど)を検出し、「threaded」に応答する場合は、要求された場合にそれをスレッド化するように設定します。きちんと。
私は最近自分でJRubyにアクセスしており、MRIからJRubyに切り替えるのがいかに簡単であるかに非常に驚いています。ほとんどの場合、いくつかの宝石を交換する必要があります。
JRubyとTrinidad(App Server)の組み合わせを確認する必要があります。 Torqueboxはまた、興味深いオールインワンソリューションであるように見えます。それは、単なるアプリサーバーだけではありません。
スレッドをサポートするアプリサーバーが必要で、Mongrel、Thin、Unicornなどに精通している場合は、ユーザーの観点から見るとほとんど同じなので、トリニダードはおそらく最も簡単に移行できます。これまで愛してる!