Подтвердить что ты не робот

Как удалить задание в sidekiq

Я использую sidekiq в моем приложении rails. Пользователи моего приложения создают отчеты, которые запускают работу sidekiq. Однако иногда пользователи хотят отменить "обработку" отчетов. Удаление отчета легко, но мне также необходимо удалить работу sidekiq.

До сих пор мне удалось получить список таких работников:

workers = Sidekiq::Workers.new

и каждый рабочий имеет аргументы, которые включают report_id, поэтому я могу определить, какая работа принадлежит какому отчету. Тем не менее, я не уверен, как фактически удалить работу. Следует отметить, что я хочу удалить задание, независимо от того, занят ли он в данный момент или повторить попытку.

4b9b3361

Ответ 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