Rails にアプリケーションがあり、ユーザーがある特定のページから別のページに移動するときに、データベース ストアド プロシージャを非同期的に実行しようとしています。ユーザーは、ストアド プロシージャの実行中にナビゲーションを続行する必要があります。
手順が終了したときにコールバックを行う必要はありません。バックグラウンドで実行するだけで済みます。
次のコードを使用しようとしています。
require 'eventmachine'
require 'em-http'
require 'fiber'
def async_fetch(url)
f = Fiber.current
http = EventMachine::HttpRequest.new(url).get :timeout => 10
http.callback { f.resume(http) }
http.errback { f.resume(http) }
return Fiber.yield
end
EventMachine.run do
Fiber.new{
url = url_for :controller => 'common', :action => 'execute_stored_procedure'
data = async_fetch(url)
EventMachine.stop
}.resume
end
ここでの問題は、ストアド プロシージャの開始時にユーザーを別のページにリダイレクトする必要がありますが、次のページは「保留中」のままで、プロシージャが終了したときにのみレンダリングされることです。
--threaded オプションを使用してサーバーとして (開発環境で) thinを使用しようとしましたが、成功しませんでした。現在、運用サーバーで Phusion Passenger Enterprise をマルチスレッド モードで使用することを考えていますが、これは商用バージョンであり、実行されます。トライアルはありません。私が必要としているものではないのではないかと心配しています。
これを達成するための良い解決策を知っている人はいますか? ストアド プロシージャを実行するには、アプリケーションが実行されているのと同じ Web サーバーにリクエストを送信する必要があるため、Web サーバーは一度に複数の接続 (マルチスレッド) を受け入れる必要がありますが、正しいですか?
役立つ情報:
- ルビー 1.9.3p385
- レール 3.2.13
- SQL Server 2012
発達:
- Linux lucid32 2.6.32-45-generic #102-Ubuntu (vagrant マシン)
- シンウェブサーバー
製造:
- Linux デビアン 2.6.32-5-xen-amd64
- Apache / Phusion パッセンジャー
どんな助けでも本当に感謝しています。
更新 #1
ジェシーさんのお勧めでセルロイドにしてみました。これが私のコードです:
require 'celluloid/autostart'
class PropertyWorker
include Celluloid
def engage(args)
ActiveRecord::Base.execute_procedure("gaiainc.sp_ins_property_profiles", args[:id])
end
end
...
def create
@property = Property.new(params[:property])
respond_to do |format|
if @property.save
PropertyWorker.new.async.engage({:id => @property.id})
format.html { redirect_to new_enterprise_property_activation_url(@property.enterprise.id, @property.id) }
format.json { render json: @property, status: :created, location: @property }
else
format.html { render action: "new" }
format.json { render json: @property.errors, status: :unprocessable_entity }
end
end
end
その後、アクション「作成」が呼び出されると、レコードが作成され、ストアド プロシージャが開始されますが、次のページはレンダリングされず、プロシージャが終了するまでリクエストはブラウザで「保留中」のままになります。手順が完了するとすぐに、ページがレンダリングされます。
何が起こっているのかわかりません。手順はバックグラウンドで実行されるはずではありませんでしたか?