Ответ 1
Чтобы вручную вызвать задание
Delayed::Job.find(10).invoke_job # 10 is the job.id
Это не удаляет задание, если оно выполняется успешно. Вам нужно удалить его вручную:
Delayed::Job.find(10).destroy
Отложенная функция автозадания задана отлично, но есть работа, которую я хочу вручную повторить вручную. Есть ли способ, который я могу вызвать на работу, как...
Delayed::Job.all[0].perform
или запустить или что-то еще. Я пробовал несколько вещей и расчесывал документацию, но не мог понять, как выполнить ручную повторную работу.
Чтобы вручную вызвать задание
Delayed::Job.find(10).invoke_job # 10 is the job.id
Это не удаляет задание, если оно выполняется успешно. Вам нужно удалить его вручную:
Delayed::Job.find(10).destroy
Delayed::Worker.new.run(Delayed::Job.last)
Это приведет к удалению задания после его завершения.
Вы можете сделать это точно так, как вы сказали, найдя работу и выполнив выполнение.
Однако, что я обычно делаю, просто установите run_at обратно, чтобы обработчик заданий снова взял его.
У меня есть метод в контроллере для тестирования, который просто сбрасывает все замедленные задания, когда я нажимаю 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
Предыдущие ответы могут быть устаревшими. Я обнаружил, что мне нужно установить fail_at, locked_by и locked_at в nil:
(для каждого задания, которое вы хотите повторить):
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
, следуя предложению Джо Мартинеса, хороший способ повторить все ваши отложенные задания:
Delayed::Job.all.each{|d| d.run_at = Time.now; d.save!}
если у вас не выполнено задание с задержкой, которое необходимо выполнить повторно, тогда вам нужно будет только выбрать их и установить, что все ссылаются на неудачные попытки повторения на 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)
Поместите это в файл инициализации!
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!
Это в основном вернет задание обратно в очередь и обработает его в обычном режиме.