Как удалить задание в sidekiq
Я использую sidekiq в моем приложении rails. Пользователи моего приложения создают отчеты, которые запускают работу sidekiq. Однако иногда пользователи хотят отменить "обработку" отчетов. Удаление отчета легко, но мне также необходимо удалить работу sidekiq.
До сих пор мне удалось получить список таких работников:
workers = Sidekiq::Workers.new
и каждый рабочий имеет аргументы, которые включают report_id, поэтому я могу определить, какая работа принадлежит какому отчету. Тем не менее, я не уверен, как фактически удалить работу. Следует отметить, что я хочу удалить задание, независимо от того, занят ли он в данный момент или повторить попытку.
Ответы
Ответ 1
В соответствии с этой страницей документации Sidekiq, чтобы удалить задание с помощью одного идентификатора, вам нужно повторить очередь и вызвать .delete
на нем.
queue = Sidekiq::Queue.new("mailer")
queue.each do |job|
job.klass # => 'MyWorker'
job.args # => [1, 2, 3]
job.delete if job.jid == 'abcdef1234567890'
end
Существует также плагин под названием sidekiq-status, который предоставляет вам возможность отменить одно задание
scheduled_job_id = MyJob.perform_in 3600
Sidekiq::Status.cancel scheduled_job_id #=> true
Ответ 2
У меня была та же проблема, но разница в том, что мне нужно было отменить запланированное задание, и мое решение:
Sidekiq::ScheduledSet.new.each do |_job|
next unless [online_jid, offline_jid].include? _job.jid
status = _job.delete
end
Ответ 3
Самый простой способ найти это:
job = Sidekiq::ScheduledSet.new.find_job([job_id])
где [job_id] - это JID, относящийся к отчету. Далее следуют:
job.delete
Мне не нужно было перебирать всю очередь, как описано в других ответах здесь.
Ответ 4
Если вы хотите отменить запланированное задание, я не уверен в ответе @KimiGao, но это то, что я адаптировал из документации по текущему API Sidekiq:
jid = MyCustomWorker.perform_async
r = Sidekiq::ScheduledSet.new
jobs = r.select{|job| job.jid == jid }
jobs.each(&:delete)
Надеюсь, что это поможет.
Ответ 5
Вы можете удалить фильтрацию sidekiq с помощью класса employee и args:
class UserReportsWorker
include Sidekiq::Worker
def perform(report_id)
# ...
end
end
jobs = Sidekiq::ScheduledSet.new.select do |retri|
retri.klass == "UserReportsWorker" && retri.args == [42]
end
jobs.each(&:delete)
Ответ 6
У меня была та же проблема.
Я решил это, зарегистрировав идентификатор задания, когда я его инициализирую, и создав еще одну функцию cancel!
, чтобы удалить ее.
Вот код:
after_enqueue do |job|
sidekiq_job = nil
queue = Sidekiq::Queue.new
sidekiq_job = queue.detect do |j|
j.item['args'][0]['job_id'] == job.job_id
end
if sidekiq_job.nil?
scheduled = Sidekiq::ScheduledSet.new
sidekiq_job = scheduled.detect do |j|
j.item['args'][0]['job_id'] == job.job_id
end
end
if sidekiq_job.present?
booking = job.arguments.first
booking.close_comments_jid = sidekiq_job.jid
booking.save
end
end
def perform(booking)
# do something
end
def self.cancel!(booking)
queue = Sidekiq::Queue.new
sidekiq_job = queue.find_job(booking.close_comments_jid)
if sidekiq_job.nil?
scheduled = Sidekiq::ScheduledSet.new
sidekiq_job = scheduled.find_job(booking.close_comments_jid)
end
if sidekiq_job.nil?
# Report bug in my Bug Tracking tool
else
sidekiq_job.delete
end
end
Ответ 7
Существует простой способ удаления задания, если вы знаете job_id:
job = Sidekiq::ScheduledSet.new.find_job(job_id)
begin
job.delete
rescue
Rails.logger.error "Job: (job_id: #{job_id}) not found while deleting jobs."
end