薄くてシナトラを使用してリクエストの応答を非同期的に反復します
-
08-10-2019 - |
質問
シナトラでの応答が「各可能な」オブジェクトを返した場合、シナトラのイベントループは結果を「それぞれ」し、HTTP応答としてストリーミングファッションで結果を生成します。ただし、シナトラへの同時リクエストがある場合、別のリクエストを処理する前に、1つの応答のすべての要素を繰り返します。 DBクエリの結果にカーソルがある場合、同時クエリを処理する前にすべてのデータが利用可能になるのを待つ必要があります。
私はasync-sinatraの宝石を見ました http://macournoyer.com/blog/2009/06/04/pusher-and-async-with-thin/, 、これらが私の問題を解決するだろうと考えていますが、私はこの例を試しました:
require 'sinatra/async'
class AsyncTest < Sinatra::Base
register Sinatra::Async
aget '/' do
body "hello async"
end
aget '/delay/:n' do |n|
EM.add_timer(n.to_i) { body { "delayed for #{n} seconds" } }
end
end
そしてその /delay/5
私が期待しているように、リクエストは同時に機能しません。つまり、3つのリクエストを同時に行い、Chromeのデバッガーは応答時間を約5、10、および15秒と指摘しています。
私はいくつかのセットアップを逃していますか、それとも同時にリクエストを処理するようにシナトラ/シンに伝える別の方法がありますか?
更新:これがこれの別のレンチです(またはおそらく物事をクリアする可能性があります):実行中 curl -i http:// localhost:3000/delay/5
同時に正しい動作があります(それぞれ2つの要求が約5秒で戻ってきます)。ランニング ab -c 10 -n 50 http:// locahost:3000/delay/5
(Apacheベンチマークユーティリティ)も合計時間(〜25秒)に合理的なものを返します。 FirefoxはChromeと同じ動作を示します。コマンドラインユーティリティとは異なるブラウザは何ですか?
解決
そのため、最終的には、この例が実際に機能し、最終的にシナトラにそれぞれの結果を同時にストリーミングさせることができることがわかりました。 EM.defer
プッシャーと非同期ページのアイデア。 CurlとApacheのベンチマークは、これが機能していることを確認しました。
ブラウザで動作しなかった理由は、ブラウザが同じURLへの接続の数を制限するためです。私は、単一のドメインへの接続接続に制限があることを知っていましたが(また少ない数)、1つのURIへのすべての接続がシリアル化されていることではありません。
http://maillist.caucho.com/pipermail/resin-interest/2009-august/003998.html
これが構成可能かどうかはわかりませんが、Firefoxにドメイン全体の構成のみが表示されますが、それが問題でした。
他のヒント
オブジェクトの応答を処理しようとしているときは、これを行います。
fork do
handle request...
exit 99
end
そして、あなたがこの子のプロセスが終了するのを待つ必要がない場合..
child = fork do
handle request...
exit 99
end
Process.detach(child)
これは複数のリクエストを処理する簡単な方法ですが、これらのDBクエリに使用しているORMがわかりませんが、DBをヒットしようとする複数のプロセスでテーブル/行レベルのロックの問題になる可能性があります。リクエストの処理を言うときの意味...