3

電子メールを送信するためにdelayed_job gemを実行しているレールアプリを維持しています。

アプリケーションのバグが原因で、ここ数日、遅延していたすべてのジョブが失敗していることに気付きました。現在、バグは修正されており、ジョブをできるだけ早く処理したいのですが、すでに失敗した試行が多すぎて、ワーカーがデータベースからジョブを取得するのに大きな遅延が生じています。

delayed_jobs テーブルを更新して、試行回数をより少ない数に設定し、run_at 属性を現在の時刻に設定してみましたが、それでも役に立ちませんでした。

ワーカーに強制的に実行させる方法を教えてください。

4

4 に答える 4

10

手動で開始できます。試してみてください

Delayed::Job.all.each { |j| j.invoke_job }

また

Delayed::Job.all.each { |j| j.payload_object.perform }
于 2012-07-19T09:40:55.797 に答える
3

既存の回答にはこれが正確に当てはまるものはないため、ここに追加します。

魔法は、遅延ジョブが実際に失敗していないことを納得させることです。そのため、rails db コンソールを介して:

-> rails db
development# update delayed_jobs set run_at = now() - interval '3 hours', attempts = 0, failed_at = null;
UPDATE 30
development# \q

-> rake jobs:workoff  # a good one to use, because it will return immediately if no jobs are found

「failed_at」または attempts フィールドのいずれかによって、ジョブが実行されない可能性があります。

于 2013-11-12T17:30:40.247 に答える
3

よし、やっと手に入れた!

トリックは実際には run_at 属性を現在の時刻に更新することでしたが、アプリの現在の時刻はデータベースから 3 時間遅れていました。

now() - interval '3 hours' に設定すると、すべてのジョブが処理されました。

編集:

@rodzyn、私はあなたの提案を試しましたが、それでもうまくいきませんでした:

[20] pry(main)> Delayed::Job.all.size
  Delayed::Backend::ActiveRecord::Job Load (0.6ms)  SELECT "delayed_jobs".* FROM "delayed_jobs" 
=> 1
[21] pry(main)> Delayed::Job.first.invoke_job
  Delayed::Backend::ActiveRecord::Job Load (0.5ms)  SELECT "delayed_jobs".* FROM "delayed_jobs" LIMIT 1
  Order Load (0.4ms)  SELECT "orders".* FROM "orders" WHERE "orders"."id" = $1 LIMIT 1  [["id", "328"]]
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
=> nil
[22] pry(main)> Delayed::Job.all.size
  Delayed::Backend::ActiveRecord::Job Load (0.6ms)  SELECT "delayed_jobs".* FROM "delayed_jobs" 
=> 1
[23] pry(main)> 
于 2012-07-19T10:07:01.093 に答える
1

現在、バグは修正されており、ジョブをできるだけ早く処理したいのですが、すでに失敗した試行が多すぎて、ワーカーがデータベースからジョブを取得するのに大きな遅延が発生しています。

つまり、ジョブはテーブルから削除されないため、遅延ジョブの試行がまだ残っています。遅延ジョブのデフォルトの動作は、使用可能なジョブを見つけるときにキューから 5 つのジョブを読み取ることです。コードをあまり変更しない方法の 1 つは、キューからより多くのジョブを取得して実行する遅延設定を設定することです。を設定することで設定できますDelayed::Worker.read_ahead

# config/initializers/delayed_job_config.rb
Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.read_ahead = 10

Delayed::Worker.destroy_failed_jobs最大試行回数後にジョブが削除されるのを回避します。これも構成可能な項目です。

遅延ジョブは、データベースで 5 秒ごとに使用可能なジョブをチェックし、5 + N ** 4 秒後に特定のジョブを試行します。したがって、特定のジョブがすでに 24 回失敗した場合、その順番は 331781 秒後に到着します。つまり、私が間違っていなければ、およそ 3 日後です。

于 2012-07-19T09:45:38.333 に答える