Sidekiq 瞬态错误与致命错误
Sidekiq transient vs fatal errors
有没有一种方法可以告诉 Sidekiq "this error is fatal and unrecoverable, do not retry, send it straight to dead job queue"?
查看 Sidekiq Error Handling 文档,它似乎将所有错误解释为暂时的,并且无论错误类型如何都会重试作业(如果启用重试)。
您应该挽救那些特定错误,而不是 re-raise 它们。
def perform
call_something
rescue CustomException
nil
end
编辑:
好吧,如果你想有意向 DLQ/DJQ 发送消息,你需要创建一个方法来完成 #send_to_morgue
的功能。我确定迈克·佩勒姆 (Mike Perham) 会因为我提出这个建议而冲我大喊大叫,但是...
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
进入那个方法的样子,但我怀疑它通常是在解析之前命中中间件的东西。
如果在 GitHub 上找到了您问题的解决方案。在那个 post 中,他们建议编写一个自定义中间件来处理您想要防止重试的异常。这是一个基本示例:
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
有没有一种方法可以告诉 Sidekiq "this error is fatal and unrecoverable, do not retry, send it straight to dead job queue"?
查看 Sidekiq Error Handling 文档,它似乎将所有错误解释为暂时的,并且无论错误类型如何都会重试作业(如果启用重试)。
您应该挽救那些特定错误,而不是 re-raise 它们。
def perform
call_something
rescue CustomException
nil
end
编辑:
好吧,如果你想有意向 DLQ/DJQ 发送消息,你需要创建一个方法来完成 #send_to_morgue
的功能。我确定迈克·佩勒姆 (Mike Perham) 会因为我提出这个建议而冲我大喊大叫,但是...
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
进入那个方法的样子,但我怀疑它通常是在解析之前命中中间件的东西。
如果在 GitHub 上找到了您问题的解决方案。在那个 post 中,他们建议编写一个自定义中间件来处理您想要防止重试的异常。这是一个基本示例:
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