Manually Retry Job in Delayed_job

Ruby on-RailsRubyRubygemsDelayed Job

Ruby on-Rails Problem Overview


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.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

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

Solution 2 - Ruby on-Rails

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

This will remove the job after it is done.

Solution 3 - Ruby on-Rails

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.

Solution 4 - Ruby on-Rails

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

Solution 5 - Ruby on-Rails

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!

Solution 6 - Ruby on-Rails

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

Solution 7 - Ruby on-Rails

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!}

Solution 8 - Ruby on-Rails

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

Solution 9 - Ruby on-Rails

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMichael WaxmanView Question on Stackoverflow
Solution 1 - Ruby on-RailsThe WhoView Answer on Stackoverflow
Solution 2 - Ruby on-RailsBeena ShettyView Answer on Stackoverflow
Solution 3 - Ruby on-RailsJoe MartinezView Answer on Stackoverflow
Solution 4 - Ruby on-RailsTonyView Answer on Stackoverflow
Solution 5 - Ruby on-RailsjpwView Answer on Stackoverflow
Solution 6 - Ruby on-Railsmohamed-ibrahimView Answer on Stackoverflow
Solution 7 - Ruby on-RailsDarmeView Answer on Stackoverflow
Solution 8 - Ruby on-RailsrubycopView Answer on Stackoverflow
Solution 9 - Ruby on-RailsBlair AndersonView Answer on Stackoverflow