如何在不重试中间件的情况下推迟sidekiq作业?

时间:2019-01-08 10:14:27

标签: ruby sidekiq

有没有一种方法可以将作业从sidekiq服务器中间件推回队列?还是只是简单地重试而不计算?

UDPATE:我的背景:我需要跟踪Elasticsearch中的工作状态(一个工作接一个工作),但是如果无法访问Elastic,并且我重新安排同一位工作人员的工作,我将失去工作链(变更) )。

2 个答案:

答案 0 :(得分:1)

最简单的方法是让作业重新安排自己的时间,然后退出。例如:

class MyJob < ApplicationJob
  queue_as :default

  def perform(*args)
    if ready_to_perform?
      # Do stuff!
    else
      MyJob.perform_later(args)
    end
  end
end

请谨慎使用。您可能不希望工作被卡住,永远重新安排自己的时间!

这与“在不增加重试计数器的情况下重试”(实现起来有点复杂)并不完全相同,但是对于像这样的大多数用例就足够了。

答案 1 :(得分:0)

这不是有效的代码,但是类似的东西可以帮助您实现所需的愿望。

您可以定义一个中间件,并将其添加到sidekiq中,如下所示

Sidekiq.configure_server do |config|
  config.server_middleware do |chain|
    chain.add Sidekiq::RetryMonitoringMiddleware
  end
end

现在,您可以按如下所述在中间件中进行定义:

class Sidekiq::RetryMonitoringMiddleware
  def call(worker, job_params, _queue)
    #calling the worker perform method to add it to the queue
    worker.perform(job_params['jid'], *job_params['args']) if should_retry?(job_params)
  rescue StandardError => e
    Rails.logger.error e
  ensure
    yield
  end

  private

  def should_retry?(job)
    # If worker is having a failure flag then only it should return a response
    # Need to check in which key we get a failure message
    (Integer(job['failure'])) == (1 || "true")
  end
end

希望有帮助!