【问题标题】:ActiveJob Serialization: no call to deserializeActiveJob 序列化:不调用反序列化
【发布时间】:2017-02-11 17:31:31
【问题描述】:

所以我正在尝试实现来自here 的相当简单的示例,它覆盖了 ActiveJobs 的序列化和反序列化方法,以在作业重试之间保存一个尝试数整数。

我已尝试在 RAILS 4.2.7.1 上将示例实施到我的项目中,结果如下:

  • 一个非常简单且使用“active_elastic_job”队列的作业类

    class Job < ActiveJob::Base
      queue_as :a_queue
    
      def serialize
        super.merge('attempt_number' => (@attempt_number || 0) + 1)
      end
    
      def deserialize(job_data)
        super
        @attempt_number = job_data['attempt_number']
      end
    
      rescue_from(Exceptions::NetworkError) do |error|
        logger.info "#{error}"
        if @attempt_number > 10
          logger.info "Drop"
        else
          logger.info "Attempt #{@attempt_number}"
          retry_job wait: 1.hour
        end
      end
    
      def perform(id)
         ...
      end
    end
    
  • 在 after_create 上使用 Job 的模型

    class Model
      after_create do
        Job.perform_later(self.id)
      end
    end
    
  • 最后是一个旨在通过 Webmock 触发重试的 RSpec 测试

    RSpec.describe CategorizerJob, type: :job do
      include ActiveJob::TestHelper
    
      # Some let calls for url, json and create
    
      context 'retry ctx' do
    
       it '404' do
         stub_request(:get, url).to_return(body: json, status: 404)
    
         perform_enqueued_jobs do
           expect_any_instance_of(Job)
           .to receive(:retry_job).with(wait: 1.hour)
           create()
         end
       end
    
    end
    

现在问题来了,反序列化方法似乎永远不会被调用,因为我尝试在其中添加 binding.pry 但无济于事。 我在运行 RSpec 时得到的只是以下问题,我认为这是由于缺少对反序列化的调用:

    Failure/Error: if @attempt_number > 10

         NoMethodError:
          undefined method `>' for nil:NilClass

任何人都可以帮助我吗?如果即使用另一种方法来实现类似的功能。

【问题讨论】:

    标签: ruby-on-rails activerecord serialization rspec amazon-elastic-beanstalk


    【解决方案1】:

    我遇到了类似的问题,发现应该在 ActiveJob::Base 子类上覆盖的方法是 deserialize_arguments。这是执行作业时的堆栈跟踪:

    activejob-4.2.8/lib/active_job/arguments.rb:42:in `deserialize'
    activejob-4.2.8/lib/active_job/core.rb:90:in `deserialize_arguments'
    activejob-4.2.8/lib/active_job/core.rb:80:in `deserialize_arguments_if_needed'     
    activejob-4.2.8/lib/active_job/execution.rb:30:in `perform_now'                    
    activejob-4.2.8/lib/active_job/execution.rb:21:in `execute' 
    

    尽管文档中的示例另有说明,但 deserializeActiveJob::Arguments 中定义。

    【讨论】:

      【解决方案2】:

      尝试调用它

      ActiveJob::Arguments.deserialize(arguments)
      

      【讨论】:

        【解决方案3】:

        您有一个 NetworkError 异常。我认为您应该查看适配器的连接选项并找出它发生的原因。

        【讨论】:

        • NetworkError异常是正常的。正如我所说,rspec 旨在通过回答 404 来触发rescue_from 中的重试,这会引发异常。现在我知道我不应该重试 404,这只是一个例子。此外,我需要帮助的地方是序列化,由于某种原因不会反序列化,这意味着我在执行“if @attempt_number > 10”时得到一个 nil 对象,因此出现错误。
        • 您可以在此处阅读有关 ActiveJob 中的序列化和反序列化的更多信息:karolgalanciak.com/blog/2016/09/25/…
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-25
        • 2011-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多