如果ActiveJob应该执行的对象被删除,我怎么能阻止它执行?

时间:2018-02-16 05:50:44

标签: ruby-on-rails rails-activejob

我有一个后台工作,对上传的图像做了一些工作,但有时在执行后台作业之前用户删除了图像,并创建了ActiveJob::DeserializationError

我可以在before_destroy中的模型中取消作业吗?或者在before_perform中我可以在作业类中执行某些操作,以便在数据库中删除记录时不执行作业?

谢谢!

3 个答案:

答案 0 :(得分:2)

活动作业实例包括ActiveSupport::Rescuable,这意味着您可以像在控制器中一样使用rescue_from作业。

然后,您可以从任何反序列化错误中恢复:

class MyJob < ApplicationJob

  rescue_from(ActiveJob::DeserializationError) do |e|
    true 
  end

end

如果要在很多作业中使用此模式,可以将其提取到模块中:

module DeserializationErrorIsOkay

  extend ActiveSupport::Concern

  included do
    rescue_from(ActiveJob::DeserializationError) do |e|
      # This error is okay and doesn't indicate a failed job
      true
    end
  end

end

你可以把它包括在你的工作中:

class MyJob < ApplicationJob
  include DeserializationErrorIsOkay
end

注意:这可以从作业中序列化的任何对象中恢复,但无法反序列化

答案 1 :(得分:0)

处理在作业类中删除或未删除的记录

begin
    record.reload
    # if no exception continue executing job
rescue ActiveRecord::RecordNotFound => e
    # If deleted exception is raised and skip executing the job
end

答案 2 :(得分:0)

这可能是一个更新的答案:

discard_on ActiveJob::DeserializationError

见:https://edgeguides.rubyonrails.org/active_job_basics.html#retrying-or-discarding-failed-jobs

示例:

class RemoteServiceJob < ApplicationJob
  retry_on CustomAppException # defaults to 3s wait, 5 attempts

  discard_on ActiveJob::DeserializationError

  def perform(*args)
    # Might raise CustomAppException or ActiveJob::DeserializationError
  end
end