【问题标题】:What happens when you pass an object to an ActiveJob enqueue and that object no longer exists at perform time?当您将对象传递给 ActiveJob 队列并且该对象在执行时不再存在时会发生什么?
【发布时间】:2015-08-15 02:10:55
【问题描述】:

如果要创建一个 ActiveJob 并且 perform 块接受一个预期为 ActiveRecord 对象的单个实例的参数,那么当作业入队时,有问题的对象存在,但在实际执行时该对象不存在了,这个工作显然会失败,对吧?

MyJob < ActiveJob::Base
  def perform(widget)
    # do some stuff to widget
  end
end

因此,一旦由于 ActiveJob 无法实例化原始 ActiveRecord 对象而导致此作业失败,它将继续失败。可以对作业进行哪些更新以停止故障循环。我考虑过连接before_perform,但我还没有看到前进的道路。

除了解决手头的问题之外,我在这里学到的另一件事是传递 widget_id 整数而不是 ActiveRecord 对象会更好。然后我就可以检查并查看有问题的小部件是否仍然存在于执行块内。

【问题讨论】:

标签: ruby-on-rails rails-activejob


【解决方案1】:

您可以rescue_from ActiveJob::DeserializationError 在找不到对象时抛出。注意:这种反序列化发生在执行回调开始之前,这就是您可以使用执行回调来处理这种情况的原因。

所以,在你的工作类中,你可以添加:

class MyJob < ActiveJob::Base

  rescue_from(ActiveJob::DeserializationError) do |exception|
    # return true (we rescued) if the error causing the deserialization
    # error was a record not being found
    exception.original_exception == ActiveRecord::RecordNotFound
  end
end

如果rescue_from 返回true,则表明错误已得到处理并且作业已成功完成。在这种情况下,我刚刚检查了导致反序列化错误的错误是否是ActiveRecord::RecordNotFound(这是 ActiveJob 用于序列化和反序列化 ActiveRecord 对象时找不到对象时导致的globalid gem)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2017-06-20
    • 2012-03-18
    • 1970-01-01
    • 2023-03-15
    • 2015-11-16
    • 1970-01-01
    • 2013-06-03
    相关资源
    最近更新 更多