Ruby on rails 如何处理';记录不存在';错误并阻止后台作业尝试重试?
Rails应用程序具有调用服务对象的后台作业,如下所示Ruby on rails 如何处理';记录不存在';错误并阻止后台作业尝试重试?,ruby-on-rails,error-handling,rails-activejob,Ruby On Rails,Error Handling,Rails Activejob,Rails应用程序具有调用服务对象的后台作业,如下所示 class ObjectUpdateJob < ActiveJob::Base queue_as :default def perform(object_id) ObjectUpdater.call(object_id) end end class ObjectUpdater def self.call(*args) if @object = Object.find( args[:object_i
class ObjectUpdateJob < ActiveJob::Base
queue_as :default
def perform(object_id)
ObjectUpdater.call(object_id)
end
end
class ObjectUpdater
def self.call(*args)
if @object = Object.find( args[:object_id] )
#... update some stuff from external services
else
#... raise an error and prevent the background job from attempting to retry
end
end
end
class ObjectUpdateJob
这可能是一个简单的问题,但我在错误处理方面的经验有限,如果您能再考虑一下,我将不胜感激
处理此“记录不存在”情况的“Rails方法”是什么,并确保后台作业得到通知,以便不尝试重试?您可以在工作人员的
执行操作中加入一个保护子句:
class ObjectUpdateJob < ActiveJob::Base
queue_as :default
def perform(object_id)
return unless Object.find(object_id)
ObjectUpdater.call(object_id)
end
end
这样,您就不会让不存在的对象被处理。如果您使用Sidekiq,您可以将一个标志设置为:retry=>false
,这样作业就不会自动重试
此外,Sidekiq还内置了错误处理机制。以下是关于此事的更多信息:
希望对您有所帮助。您可以轻松地以rails的方式处理异常。但不知道如何防止作业重试。我没有看到它的任何文档。该对象可能在排队后被删除,因此最好同时选中两个checksHanks@AndreyDeineko,这很有用。如果你能回答一些问题来帮助我理解这一点,我将不胜感激。(1) 在这种情况下,调用fail-ActiveRecord::RecordNotFound'string'
与调用fail'string'
相比,有哪些优点/缺点?(2) 您建议调用一个服务对象,它启动一个后台作业,调用一个服务对象。这是常见的吗?我担心这会给代码增加混乱?(3) 我以前从未遇到过=Struct.new(:id)
。它似乎替换了初始化
方法。这是正确的吗?您能指出任何文档吗?谢谢@而且哈维也不确定,对我来说,失败总是足够的。。2) 你是对的,我错了,我不知道我在想什么。你完全正确,不要这样做。但是它的思想很简单,只需在调用worker的地方创建一个guard子句,比如ObjectUpdateJob.perform\u now(object\u id)if object.find(object\u id)
。这+在perform
中有return语句应该足以不处理不存在的记录。3) 是的,这对于诸如服务对象之类的东西非常有用。另一个选项是覆盖ActiveJob::Core
sinitialize
方法,将fail
放在那里。你可以考虑,但你知道,修补栏杆似乎不是超级清洁。solution@AndyHarvey让我知道,如果我能帮助你进一步感谢@rii,我真正想要的是一种在非常特殊的情况下防止退休的方法,而不是在全球范围内。e、 例如sidekiq\u选项:retry=>false,除非Object.find(args[:Object\u id])
。有什么想法吗?
ObjectUpdateJob.perform_now(object_id) if Object.find(object_id)