31

新しいリソースが作成され、リソースの準備が整う前に長い処理を行う必要がある場合、その処理をバックグラウンドに送信して、現在のリクエストや Web アプリへの他のトラフィックを保持しないようにするにはどうすればよいですか?

私のモデルでは:

class User < ActiveRecord::Base
 after_save :background_check

 protected
 def background_check
  # check through a list of 10000000000001 mil different
  # databases that takes approx one hour :)
  if( check_for_record_in_www( self.username ) )
    # code that is run after the 1 hour process is finished.
    user.update_attribute( :has_record )
  end
 end
end
4

7 に答える 7

42

次のRailscastをぜひチェックしてください。

Rails でバックグラウンド プロセスを実行する方法をあらゆる方法で説明しています (キューの有無にかかわらず ...)。

于 2009-05-22T14:38:27.423 に答える
7

system別のプロセスを開始します。これはおそらく、「nohup」を先頭に追加し、渡したコマンドの最後に「&」を追加することで最も簡単に実行できます。(コマンドが引数のリストではなく、1つの文字列引数であることを確認してください。)

たとえば、スレッドを使用しようとするのではなく、この方法で実行したい理由はいくつかあります。

  1. Rubyのスレッドは、I/Oの実行に関しては少し注意が必要です。プロセス全体がブロックされないように注意する必要があります。

  2. 別の名前でプログラムを実行すると、「ps」で簡単に識別できるため、FastCGIバックエンドがワイルドになったなどと誤って考えて強制終了することはありません。

実際、開始するプロセスは「デーモン化」されている必要があります。ヘルプについては、デーモン化クラスを参照してください。

于 2009-05-22T12:44:31.710 に答える
2

独自のバックグラウンド ジョブ サーバーを作成するのではなく、既存のバックグラウンド ジョブ サーバーを使用することが理想的です。これらは通常、ジョブを送信して一意のキーを与えることができます。その後、キーを使用して、webapp をブロックすることなく、jobserver にジョブのステータスを定期的に問い合わせることができます。これは、そこにあるさまざまなオプションの素晴らしいまとめです。

于 2009-05-22T12:57:44.350 に答える
1

spawnは、プロセスをフォークし、バックグラウンドで処理を行い、この処理が開始されたことをユーザーに確認するための優れた方法だと思います。

于 2010-03-29T14:47:38.700 に答える
1

私は backgroundrb を使用するのが好きです。これにより、長いプロセス中に通信できるようになります。したがって、Rails アプリでステータスの更新を行うことができます

于 2009-05-22T16:26:14.450 に答える
0

どうですか:

def background_check
   exec("script/runner check_for_record_in_www.rb #{self.username}") if fork == nil
end

その後、プログラム " check_for_record_in_www.rb" は別のプロセスで実行され、ActiveRecord にアクセスできるようになり、データベースにアクセスできるようになります。

于 2009-05-22T12:58:25.067 に答える