web-dev-qa-db-fra.com

comment supprimer un travail dans sidekiq

J'utilise sidekiq dans mon application Rails. Les utilisateurs de mon application créent des rapports qui démarrent un travail sidekiq. Cependant, les utilisateurs souhaitent parfois pouvoir annuler les rapports de "traitement". La suppression du rapport est facile, mais je dois également pouvoir supprimer le travail sidekiq. 

Jusqu'à présent, j'ai pu obtenir une liste de travailleurs comme celle-ci:

workers = Sidekiq::Workers.new

et chaque travailleur a des arguments qui incluent un report_id afin que je puisse identifier quel travail appartient à quel rapport. Cependant, je ne sais pas comment supprimer le travail. Il est à noter que je souhaite supprimer le travail s'il est actuellement occupé ou configuré lors d'une nouvelle tentative. 

29
Matthew Berman

Selon cette page de documentation Sidekiq pour supprimer un travail avec un identifiant unique, vous devez itérer la file d'attente et appeler .delete dessus.

queue = Sidekiq::Queue.new("mailer")
queue.each do |job|
  job.klass # => 'MyWorker'
  job.args # => [1, 2, 3]
  job.delete if job.jid == 'abcdef1234567890'
end

Il existe également un plugin appelé sidekiq-status qui vous permet d'annuler un seul travail.

scheduled_job_id = MyJob.perform_in 3600
Sidekiq::Status.cancel scheduled_job_id #=> true
56
Simone Carletti

La manière la plus simple que j'ai trouvée de faire ceci est:

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

où [id_travail] est le JID associé au rapport. Suivi par:

job.delete

Je n'ai trouvé aucun besoin de parcourir la file d'attente entière comme décrit par d'autres réponses ici.

16
Rick

J'ai eu le même problème, mais la différence est que je devais annuler un travail planifié, et ma solution est la suivante:

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

Si vous souhaitez annuler un travail planifié, je ne suis pas sûr de la réponse de @ KimiGao, mais voici ce que j'ai adapté à partir de la documentation actuelle de l'API de Sidekiq:

jid = MyCustomWorker.perform_async

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

J'espère que ça aide.

3
thekingoftruth

Vous pouvez supprimer le filtrage des travaux sidekiq par classe de travailleurs et arguments:

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)
2
Michał Kurek

J'ai eu le même problème… .. Je l'ai résolu en enregistrant l'identifiant du travail lorsque je l'initialisais et en créant une autre fonction cancel! pour le supprimer.

Voici le code:

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
1

Ou vous pouvez utiliser la page sidekiq sur le serveur Rails.

Par exemple, http: // localhost: 3000/sidekiq , vous pouvez arrêter/supprimer les travaux sidekiq.

Avant cela, vous devez mettre à jour le fichier routes.rb.

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

Il existe un moyen simple de supprimer un travail si vous connaissez le 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
0
Pushp Raj Saurabh