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.
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
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.
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
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.
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)
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
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'
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