2011-02-02 5 views
1

私は長いアイテムのリストを持っています。それぞれの横にチェックボックスがあります。 jQueryのcheck-all関数がありますが、それらのすべてを一度に提出すると、クエリの束をして、各アイテムのMySQLデータベースに一連のレコードを挿入するため、リクエストがタイムアウトします。タイムアウトしない場合は、おそらく約20分かかります。代わりに、私は一度に30のように提出するだけです。Ruby on Railsがタイムアウトしました。どのようにプロセスをフォークしますか?

私はすべてをチェックして提出してから、他の仕事をしていきたいと思っています。私の同僚(1)は、私はちょうどレーキの仕事を書くべきだと言いました。私はそれをしましたが、コードの複製が終わってしまいました。私はいくつかのチェックを外したければどうしたらいいですか?レーキタスクはそれらをすべて送信します。

他の同僚(2)が推奨私はフォークを使用します。同氏は、これによりサーバー上で実行される新しいプロセスが生成されるが、サーバーは完了する前に応答できるという。その後、アイテムは送信された後に消えるので、完了したかどうかを確認するためにページを更新することができます。

私はこれを私のローカルで試しましたが、RailsはHTMLフォームによって送信されたPOSTリクエストに応答する前にプロセスが終了するのを待っているようです。私はこのようなルックスを使用したコード:

def bulk_apply 
    pid = fork do 
    params[:ids].each do |id| 
     Item.find(id).apply # takes a LONG time, esp. x 100 
    end 
    end 
    Process.detach(pid) # reap child process automatically; don't leave running 
    flash[:notice] = "Applying... Please wait... Then, refresh page. Only submit once. PID: #{pid}" 
    redirect_to :back 
end 

同僚1は、フォークは、基本的にRailsのプロセスのコピーである子プロセスを作成するため、一般的に、あなたがRailsのをforkしたくないと言いました。彼は、あなたがWeb GUIを通してそれをやりたいのであれば、BackgroundJob(Bj)を使っていると言いました(私たちは既にRailsアプリケーションでこれを使っています)。だから、私は今BackgroundJobを探していますが、何をお勧めしますか?

答えて

2

私はバックグラウンドジョブを使って成功しました。レールが必要な場合は、スクリプト/ランナーを使用していますが、まだレールで新しいプロセスを起動します。良いことは、Backround Jobは一度に1つ以上の実行がないことを確認することです。

また、直接スクリプトランナーを使用するか、そうであっても同様にバックグラウンドでrakeタスクを実行できます。

system " RAILS_ENV=#{RAILS_ENV} ruby #{RAILS_ROOT}/script/runner 'CompositeGrid.calculate_values(#{self.id})' & " unless RAILS_ENV == "test" 

アンパサンドは、新しいプロセスを開始するように指示します。あなたはおそらくこれらの実行の束を同時に望んでいないので注意してください。すでに利用可能な場合、私はバックグラウンドジョブを利用することは間違いありません。

+0

バックグラウンドジョイントに引数としてハッシュを渡すにはどうすればよいですか? – ma11hew28

2

IronWorkerをご確認ください。あなたが望むことをするのはとても簡単ですし、どれくらい時間がかかっても問題はありません。

あなたの行動では、すべてのデータベースクエリを実行するコードを持つワーカーをインスタンス化するだけです。例ワーカー:

Item.find(id).apply # takes a LONG time, esp. x 100 

そして、ここでは、あなたが並列で実行するように、これらのジョブをキューにしたい方法は次のとおりです。

client = IronWorkerNG::Client.new 
ids.each do |id| 
    client.tasks.create("MyWorker", "id"=>id) 
end 

あなたがする必要があると思い、すべてだと鉄工は残りの世話をすること。

+0

恐ろしい、ちょうどこれを試みた! –

0

お試しdelayed_job gem。これは、データベースベースのバックグラウンドジョブの宝石です。私たちはそれを電子商取引のウェブサイトで使用しました。たとえば、注文確認メールをユーザーに送信することは、遅延ジョブの理想的な候補です。

また、Rubyでサポートされているマルチスレッドを試すこともできます。これは物事をより速く動かすことができます。プロセス全体をフォークすることは、メモリ使用のために高価になる傾向があります。

関連する問題