【问题标题】:How to handle 'record does not exist' errors and prevent background jobs from attempting retries?如何处理“记录不存在”错误并防止后台作业重试?
【发布时间】:2016-02-06 05:17:11
【问题描述】:

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_id] )
      #... update some stuff from external services 
    else 
      #... raise an error and prevent the background job from attempting to retry
    end
  end
end

这可能是一个简单的问题,但我在错误处理方面的经验是有限的,我希望能再考虑一下。

处理这种“记录不存在”情况并确保通知后台作业以便不尝试重试的“Rails 方式”是什么?

【问题讨论】:

标签: ruby-on-rails error-handling rails-activejob


【解决方案1】:

你可以在 worker 的 perform 操作中加入一个保护子句:

class ObjectUpdateJob < ActiveJob::Base
  queue_as :default

  def perform(object_id)
    return unless Object.find(object_id)
    ObjectUpdater.call(object_id)
  end
end

但为了获得更多保护,您可以检查一下工作调用:

ObjectUpdateJob.perform_now(object_id) if Object.find(object_id)

这样你就不会让不存在的对象被处理。

【讨论】:

  • 对象可能在排队后被删除,所以最好同时检查
  • 谢谢@AndreyDeineko,这很有用。感谢您能回答几个问题,以帮助我进一步理解这一点。 (1) 在这种情况下,调用fail ActiveRecord::RecordNotFound 'string'fail 'string' 的优缺点是什么? (2) 你建议调用一个服务对象,它启动一个后台作业,调用一个服务对象。这很常见吗?我担心它可能会给代码增加混乱? (3) 我以前没有遇到过= Struct.new(:id)。它似乎取代了initialize 方法。这是正确的,你能指出任何文档吗?谢谢!
  • @AndyHarvey 1) 不确定,对我来说,fail.. 2) 你是对的,我的错误 - 不知道我在想什么。你是绝对正确的,不要这样做。但它的想法很简单,只需在你调用工人的地方做一个保护子句,比如ObjectUpdateJob .perform_now(object_id) if Object.find(object_id)。这个 + 在perform 中有返回语句应该足以不处理不存在的记录。 3) 是的,Struct 对于诸如服务对象之类的东西非常有用。
  • 另一种选择是覆盖ActiveJob::Cores initialize 方法,将fail 放在那里。你可以考虑,但你知道,修补 Rails 似乎不是一个超级干净的解决方案
  • @AndyHarvey 告诉我,如果我能进一步帮助你
【解决方案2】:

如果您使用 Sidekiq,您可以将标志设置为 :retry =&gt; false,以便作业不会自动重试。

此外,Sidekiq 还内置了错误处理机制。以下是有关此事的更多信息:https://github.com/mperham/sidekiq/wiki/Error-Handling

希望对您有所帮助。

【讨论】:

  • 感谢@rii,我真正想要的是一种在非常特殊的情况下而不是在全球范围内防止退休的方法。例如,sidekiq_options :retry =&gt; false unless Object.find( args[:object_id] ) 之类的东西。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多