2010-07-22 2 views
53

Задержка: Функция автоматического повтора задания отлично, но есть работа, которую я хочу вручную повторить вручную. Есть ли способ, который я могу назвать самой работой, например ...Вручную повторить работу в Delayed_job

Delayed::Job.all[0].perform 

или запустить или что-то в этом роде. Я пробовал несколько вещей и расчесывал документацию, но не мог понять, как выполнить ручную повторную работу.

+2

'Delayed :: Worker.new.run (Delayed :: Job.first)' [ref] (http://stackoverflow.com/a/20146200/495132) –

ответ

88

Чтобы вручную вызвать при приеме на работу

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

Это не снимает работу, если она успешно работать. Вам необходимо удалить его вручную:

Delayed::Job.find(10).destroy 
+10

Альтернатива, предложенная @joe, является более безопасной, особенно если задание необходимо знать, работает ли оно в скрипте/консоли или внутри рабочего места. Попробуйте это для очереди на задание для немедленной повторной попытки Задержка: Job.first.update_attributes (: попытки => 0,: run_at => Время.now,: failed_at => nil,: locked_by => nil,: locked_at => nil) –

+8

'попытки' не могут быть назначены в' update_attributes', потому что это защищенный атрибут. Я просто делаю: 'dj = Delayed :: Job.first; dj.run_at = Time.now; dj.attempts = 0; dj.save!; ' – Anjan

+0

Чтобы сделать это en-masse, это сработало (около 100 заданий) Delayed :: Job.where.all.each {| dj | dj.run_at = Time.now; dj.attempts = 0; dj.save!} – tobinharris

11

Вы можете сделать это именно так, как вы сказали, найдя работу и работу.

Однако, что я обычно делаю, просто установите run_at так, чтобы рабочий процессор снова забирал его.

+1

Не существует метода 'execute' для отложенной работы объект. Ближайшим является 'Delayed :: Job.find (10) .payload_object.perform', и его не следует использовать. – lulalala

8

У меня есть метод в контроллере для целей тестирования, которые просто сбрасывает все отложенные задания, когда я ударил URL. Не супер элегантный, но отлично работает для меня:

# 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 
+1

use update_all .. это один вызов db. – baash05

+1

Вы не можете использовать update_all. Ebcause пытается защитить атрибут. –

+1

update_all использует SQL напрямую и, следовательно, не вызывает проверки (или защищенные атрибуты и т. Д.). – Michael

4

В среде разработки, с помощью rails console, следуя предложению Джо Мартинес, хороший способ, чтобы повторить все отложенные задания является:

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

Обновление 'run_at' в 4.0.1 не представляется достаточным. Я должен был сделать следующее: 'Delayed :: Job.where (" failed_at is not null "). Each do | dj | dj.run_at = Time.now; dj.last_error = nil; dj.failed_at = nil; dj.save! end' – steakchaser

6

Предшествующие ответы выше может быть устаревшим. Я обнаружил, что мне нужно, чтобы установить failed_at, locked_by и locked_at к нулю:

(для каждого задания вы хотите повторить):

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! 
21
Delayed::Worker.new.run(Delayed::Job.last) 

Это удалит эту работу после того, как оно сделанный.

+0

Он удалит его, даже если он сработает. – aledustet

+0

. За все отложенное задание вы можете выполнить 'Delayed :: Job.find_each (batch_size: 100) {| d | Delayed :: Worker.new.run (d)} ' – MatayoshiMariano

3

, если вы не смогли замедленную работу, которую вам необходимо повторно запустить, то вам будет нужно только выбрать их и установить все относятся к неудачной повторной попытке в нуль:

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 
0

Поместите это в файле инициализация!

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 

Затем вы можете запустить Delayed::Job.find(1234).retry!

Это будет в основном придерживаться работу обратно в очередь и обрабатывать его как обычно.

Смежные вопросы