所以我试图实现 here 中相当简单的例子它覆盖了 ActiveJobs 的序列化和反序列化方法,以在作业重试之间保存一个尝试编号的整数。
我已经尝试在我的项目中实现这个例子,在 RAILS 4.2.7.1 上,结果如下:
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
class Model
after_create do
Job.perform_later(self.id)
end
end
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
任何人都可以帮助我吗?如果甚至用另一种方式来实现类似的功能。
最佳答案
我有一个类似的问题,发现你应该在 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'
尽管文档中的示例另有说明,
deserialize
在 ActiveJob::Arguments
中定义.
关于ruby-on-rails - ActiveJob 序列化 : no call to deserialize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39837232/