0

Rails アプリケーションに「バックグラウンド」スレッドのようなものを追加したいと考えています。ときどき (たとえば 10 分ごとに) メールをチェックし、メールに従って何かをする必要があります。これは、バグ トラッカーと同じように機能するはずです。バグ トラッカーから受け取った電子メールに返信すると、その電子メールがチケットに追加されます。

バックグラウンドでこのようなものを実行する簡単な方法はありますか? cron やシステム ツールは使いたくありません。純粋な Ruby だけです。私はアプリケーションを開始し、他に何も気にする必要はありません。

4

4 に答える 4

3

EventMachine にはPeriodicTimerがあります

 n = 0
 timer = EventMachine::PeriodicTimer.new(5) do
   puts "the time is #{Time.now}"
   timer.cancel if (n+=1) > 5
 end

rufus-schedulerは、純粋な Ruby ベースの EventMachine で cron のような書き込みを行うツールです。

于 2012-06-01T14:25:38.987 に答える
1

指摘する価値のある、受け入れられた回答にはいくつかの潜在的な問題があります。

最初に、PeriodicTimer末尾再帰を使用して、つまり、EventMachine.add_timerそのブロックを実行した後に呼び出すことによって、実行のために自分自身を再スケジュールします。残念ながら、コードは使用していませんbegin-ensure-end。つまり、コードに例外がある場合、タイマーは停止します。GH#454を参照してください。

EventMachine第 2 に、シングルトンとしてシングル スレッドで実行されている のリアクター ループの問題があります。を開始しPeriodicTimer、そのブロックで遅い電子メール操作を実行すると、他のコードが依存しているリアクター ループがブロックされます。より良いアプローチは、メール収集作業を を使用して別のスレッドにプッシュすることEventMachine::Deferrableです。例については、この投稿を参照してください。

最後になりましたがEventMachine、リアクターがまだ実行されていない場合は別のスレッドで実行する必要がありますが、リアクターのスレッドが既に実行されている場合は、作業を「スケジュール」する必要があります。

これをまとめると、次のようになります。

def check_email
  timer = EM::PeriodicTimer.new(10.minutes) do
    begin
      DefferableEmailChecker.new.errback do |error|
        # handle error
        # note that this code will run OUTSIDE the
        # periodic timer block
      end
    rescue Exception => e
      # even with a Deferable this is good practice
      # if you want to cancel, use timer.cancel
    end
  end
end

if EM.reactor_running?
  EM.schedule do
    check_email
  end
else
  Thread.new do
    EM.run do
      check_email
    end
  end
end
于 2013-07-25T23:57:17.640 に答える
0

私はプロジェクトでdelayed_jobを使用しています。

Delayed_job (または DJ) は、バックグラウンドでより長いタスクを非同期に実行する一般的なパターンをカプセル化します。

于 2012-06-01T14:30:22.303 に答える
0

Daemon-Kit をチェックしてください。これにより、Rails のプロジェクトと同様の規則を持つフレームワークで Ruby デーモンを作成できます。これを使用して、さまざまなバックグラウンド タスクを監視および実行します。

于 2012-06-01T14:30:01.317 に答える