解決
開発モードでユニコーンに切り替えています。デッドロック状態を防ぐために、再帰のレベルごとに1つのワーカープロセスが必要なので、2つのワーカープロセスで実行しています。
問題
開発環境でThinサーバーに取り組んでいます。ポート3000(開発環境のデフォルト)を使用しています。私の問題は、サーバーがそれ自体に要求を行うようにすることです。
次のコントローラーがあるとしましょう。
# app/controllers/recursions_controller.rb
class RecursionsController < ApplicationController
# /recursions
def index
# synchronously call recursions#show
RestClient.get("http://localhost:3000/recursions/1")
# finish!
render :text => 'index'
end
# /recursions/:id
def show
# finish immediately
render :text => 'show'
end
end
対応するルートは次のとおりです。
# config/routes.rb
resources :recursions
これは、最初にリクエストしたときのリクエストログからの出力ですrecursions#index
。
[INFO] 2013-01-15 12:09:05 -0800 Started GET "/recursions" for 127.0.0.1 at 2013-01-15 12:09:05 -0800
Processing by RecursionsController#index as HTML
Completed 500 Internal Server Error in 60049ms
[FATAL] 2013-01-15 12:10:05 -0800 RestClient::RequestTimeout (Request Timeout):
app/controllers/recursions_controller.rb:8:in `index'
Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.8ms)
Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.7ms)
Rendered /usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (7.4ms)
[INFO] 2013-01-15 12:10:05 -0800
[INFO] 2013-01-15 12:10:05 -0800
[INFO] 2013-01-15 12:10:05 -0800 Started GET "/recursions/1" for 127.0.0.1 at 2013-01-15 12:10:05 -0800
Processing by RecursionsController#show as XML
Parameters: {"id"=>"1"}
Rendered text template (0.0ms)
Completed 200 OK in 7ms (Views: 5.5ms)
ここで起こっているのは、ある種のデッドロック状態だと思います。リクエストAはリクエストBが戻るまで戻ることができません(再帰的な順序付け、それを助けることはできません)が、リクエストBはリクエストAが戻るまで処理できません(私のWebサーバーに組み込まれている明らかな制限?)。RestClientがタイムアウトするとデッドロックが解決され、例外が発生してリクエストAが500で終了します。その場合にのみ、リクエストBが処理されますが、現時点では無効です。
私のウェブサーバーは同時リクエストを処理できないようです。そうは言っても、ここに私の質問があります:
この方法で制限されていない開発環境で切り替えることができるWebサーバーはありますか?本番環境ではUnicornを使用しており、複数のワーカープロセスを生成できるため、同時リクエストを処理できますが、Unicornは開発環境には重すぎるようです。Unicornを私の問題の解決策にするのと同じことが、ログ出力の読み取りを困難にする可能性があります。これが私の最後の手段です。
明らかな同時リクエストの制限を回避する、Rails / Rackフレームワークへのリクエストを行うためのトリッキーな方法はありますか?
誰かが私にこのlimationを明示的に述べているドキュメントを提供できますか?それがすべてのシングルプロセスRubyonRails Webサーバーに固有の制限なのか、それとも単にThinだけなのかはわかりません。
注:これは、私が抱えているブロッキングの問題を示すための単なるトイプロブレムです。これの実際の理由を知る必要がある場合は、一部のHTTPサービスをインフラストラクチャの別の部分からRoRアプリに移動しているということです。RoRアプリは、コード内のさまざまなポイントでこれらのサービスを使用するため、これらのサービスのクライアントコードはそのままにして、実装のみを変更しようとしています。これは、循環HTTPリクエストを作成することを意味します。これは、後日、すべてが安定したときに最適化されます。