Sidekiq瞬态与致命错误

时间:2017-02-13 15:53:15

标签: ruby sidekiq

有没有办法从Sidekiq的工作中错误地告诉Sidekiq"这个错误是致命的和不可恢复的,不要重试,直接发送到死队和#34;

查看Sidekiq Error Handling文档,似乎它将所有错误都解释为瞬态,并且无论错误类型如何,都会重试作业(如果启用了重试)。

2 个答案:

答案 0 :(得分:3)

你应该拯救那些特定的错误,而不是重新提升它们。

def perform
  call_something
rescue CustomException
  nil
end

编辑:

好吧,如果你想故意向DLQ / DJQ发送消息,你需要制定一个方法来完成#send_to_morgue所做的事情。我确定迈克·佩勒姆会来这里并对我大吼大叫,但是... ...

    def send_to_morgue(msg)
      Sidekiq.logger.info { "Adding dead #{msg['class']} job #{msg['jid']}" }
      payload = Sidekiq.dump_json(msg)
      now = Time.now.to_f
      Sidekiq.redis do |conn|
        conn.multi do
          conn.zadd('dead', now, payload)
          conn.zremrangebyscore('dead', '-inf', now - DeadSet.timeout)
          conn.zremrangebyrank('dead', 0, -DeadSet.max_jobs)
        end
      end
    end

唯一的区别是你必须深入研究msg看起来像是什么样的方法,但我怀疑它是解析之前通常会遇到中间件的。

答案 1 :(得分:1)

如果在GitHub上找到解决问题的方法。在那篇文章中,他们建议编写一个自定义中间件来处理你想要阻止重试的异常。这是一个基本的例子:

def call(worker, msg, queue)
  begin
    yield
  rescue ActiveRecord::RecordNotFound => e
    msg['retry'] = false
    raise
  end
end

您可以延伸:

def call(worker, msg, queue)
  begin
    yield
  rescue ActiveRecord::RecordNotFound => e
    msg['retry'] = false
    raise
  rescue Exception => e
    if worker.respond_to?(:handle_error)
      worker.handle_error(e)
    else
      raise
    end
  end
end