2

所以我試圖實現here的相當直接的例子,它覆蓋了ActiveJobs的serialize和反序列化方法,以在作業重試之間保存一個attempt_number整數。ActiveJob序列化:沒有調用反序列化

我試圖實現示例到我的項目,在軌道上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

    class Model 
        after_create do 
        Job.perform_later(self.id) 
        end 
    end 
    
  • 模型

    最後一個RSpec的測試旨在通過​​Webmock觸發重試

    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 

有人可以幫助我嗎?即使用另一種方式來實現類似的功能。

回答

-1

您有NetworkError異常。我認爲你應該看到適配器的連接選項並找出它發生的原因。

+0

NetworkError異常是正常的。正如我所說的那樣,rspec的目標是通過迴應404來觸發rescue_from的重試,這會拋出異常。現在我知道我不應該重試404,這只是一個例子。此外,我需要幫助的是序列化,由於某種原因,它並不反序列化,因此在執行「if @attempt_number> 10」時會得到一個無對象,從而導致錯誤。 – Pyos

+0

你可以在這裏閱讀更多有關ActiveJob中的序列化和反序列化: https://karolgalanciak.com/blog/2016/09/25/decoding-rails-magic-how-does-activejob-work –

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' 

Althought在文檔的例子中另外指明,在deserializeActiveJob::Arguments定義。