Как удалить работу в сидекик

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

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

workers = Sidekiq::Workers.new

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

7 ответов

Решение

Согласно этой странице документации 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

Простейший способ сделать это:

job = Sidekiq::ScheduledSet.new.find_job([job_id])

где [job_id] - это JID, который относится к отчету. С последующим:

job.delete

Я не нашел необходимости перебирать всю очередь, как описано другими ответами здесь.

У меня была та же проблема, но разница в том, что мне нужно было отменить запланированное задание, и мое решение:

Sidekiq::ScheduledSet.new.each do |_job|
  next unless [online_jid, offline_jid].include? _job.jid
  status = _job.delete
end

Вы можете удалить фильтрацию заданий sidekiq по рабочему классу и аргументам:

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)

Если вы хотите отменить запланированное задание, я не уверен насчет ответа @KimiGao, но это то, что я адаптировал из текущей документации по API Sidekiq:

jid = MyCustomWorker.perform_async

r = Sidekiq::ScheduledSet.new
jobs = r.select{|job| job.jid == jid }
jobs.each(&:delete)

Надеюсь, поможет.

Или вы можете использовать страницу sidekiq на сервере rails.

Например, http://localhost:3000/sidekiq, вы можете остановить / удалить задания sidekiq.

Перед этим необходимо обновить маршруты. Rb.

require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'

У меня такая же проблема. Я решил это путем регистрации идентификатора задания при его инициализации и создания другой функции 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

Существует простой способ удаления задания, если вы знаете 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
Другие вопросы по тегам