开发者

Manually Retry Job in Delayed_job

Delayed::Job's auto-retry feature is great, but there's a job that I want to manually retry now. Is there a method I can call on the job itself like...

Delayed::Job.all[0].perform

or run, or something. I tried a few things, and combed the documentation, but couldn't figure out how to execute a manual re开发者_JAVA技巧try of a job.


To manually call a job

Delayed::Job.find(10).invoke_job # 10 is the job.id

This does not remove the job if it is run successfully. You need to remove it manually:

Delayed::Job.find(10).destroy


Delayed::Worker.new.run(Delayed::Job.last)

This will remove the job after it is done.


You can do it exactly the way you said, by finding the job and running perform.

However, what I generally do is just set the run_at back so the job processor picks it up again.


I have a method in a controller for testing purposes that just resets all delayed jobs when I hit a URL. Not super elegant but works great for me:

# For testing purposes
  def reset_all_jobs
    Delayed::Job.all.each do |dj|
      dj.run_at = Time.now - 1.day
      dj.locked_at = nil
      dj.locked_by = nil
      dj.attempts = 0
      dj.last_error = nil
      dj.save
    end
    head :ok
  end


Prior answers above might be out of date. I found I needed to set failed_at, locked_by, and locked_at to nil:

(for each job you want to retry):

d.last_error = nil
d.run_at = Time.now
d.failed_at = nil
d.locked_at = nil
d.locked_by = nil
d.attempts = 0
d.failed_at = nil # needed in Rails 5 / delayed_job (4.1.2)
d.save!


if you have failed delayed job which you need to re-run, then you will need to only select them and set everything refer to failed retry to null:

Delayed::Job.where("last_error is not null").each do |dj|
  dj.run_at = Time.now.advance(seconds: 5)
  dj.locked_at = nil
  dj.locked_by = nil
  dj.attempts = 0
  dj.last_error = nil
  dj.failed_at = nil
  dj.save  
end


In a development environment, through rails console, following Joe Martinez's suggestion, a good way to retry all your delayed jobs is:

Delayed::Job.all.each{|d| d.run_at = Time.now; d.save!}


Delayed::Job.all.each(&:invoke_job)


Put this in an initializer file!

module Delayed
  module Backend
    module ActiveRecord
      class Job
        def retry!
          self.run_at = Time.now - 1.day
          self.locked_at = nil
          self.locked_by = nil
          self.attempts = 0
          self.last_error = nil
          self.failed_at = nil
          self.save!
        end
      end
    end
  end
end

Then you can run Delayed::Job.find(1234).retry!

This will basically stick the job back into the queue and process it normally.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜