简体   繁体   中英

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 retry 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)

这将在完成后删除作业。

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!

在开发环境中,通过rails console ,按照Joe Martinez的建议,重试所有延迟作业的好方法是:

Delayed::Job.all.each{|d| d.run_at = Time.now; 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
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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM