【问题标题】:how to delete a job in sidekiq如何在sidekiq中删除作业
【发布时间】:2021-04-12 17:54:06
【问题描述】:

我在我的 rails 应用程序中使用 sidekiq。我的应用程序的用户创建启动 sidekiq 作业的报告。但是,有时用户希望能够取消“处理”报告。删除报告很容易,但我还需要能够删除 sidekiq 作业。

到目前为止,我已经能够获得这样的工人名单:

workers = Sidekiq::Workers.new

每个工作人员都有包含 report_id 的参数,因此我可以确定哪个作业属于哪个报告。但是,我不确定如何实际删除该作业。需要注意的是,无论是当前忙,还是设置重试,我都想删除该作业。

【问题讨论】:

    标签: ruby-on-rails sidekiq


    【解决方案1】:

    根据Sidekiq documentation page,要删除具有单个 id 的作业,您需要迭代队列并在其上调用 .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】:

    我发现的最简单的方法是:

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

    其中 [job_id] 是与报告相关的 JID。其次是:

    job.delete
    

    我发现没有必要按照此处其他答案的描述遍历整个队列。

    【讨论】:

    • find_job 使用same 线性搜索。这是来自documentation 的评论:“如果您的队列很大,这将非常低效!”
    • @bartolo-otrit 你有什么建议?
    • 通过 JID 找工作(警告:如果您的队列很大,这将非常低效!)
    【解决方案3】:

    我遇到了同样的问题,但不同的是我需要取消一个预定的工作,我的解决方案是:

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

    【讨论】:

    • create_log 是干什么用的?
    【解决方案4】:

    如果您想取消预定的作业,我不确定@KimiGao 的回答,但这是我改编自 Sidekiq 当前 API 文档的内容:

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

    希望对你有帮助。

    【讨论】:

      【解决方案5】:

      您可以删除按工人类和参数过滤的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)
      

      【讨论】:

        【解决方案6】:

        我遇到了同样的问题。 我通过在初始化时注册作业 ID 并通过创建另一个函数 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】:

          或者你可以在rails服务器上使用sidekiq页面。

          例如http://localhost:3000/sidekiq,您可以停止/删除sidekiq作业。

          在此之前,您必须更新 routes.rb。

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

          【讨论】:

          • 重要的是要注意这仅适用于仍在队列中或计划中的作业。对于忙碌且仍在运行的作业,这不会改变任何事情。
          【解决方案8】:

          如果您知道 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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-10-03
            • 2021-01-21
            • 1970-01-01
            • 2017-07-29
            • 2014-06-02
            • 2014-09-13
            • 1970-01-01
            相关资源
            最近更新 更多