ruby-on-rails – 使用Sidekiq进行活动作业并获取ActiveJob :: DeserializationError

我正在尝试使用Sidekiq来完成以下工作.

未排队时执行该作业(perform_Now),但在使用Sidekiq调用(perform_later)时失败.

AddEmployeesToRoomJob.perform_Now room  ## works fine
AddEmployeesToRoomJob.perform_later room  ## breaks in Sidekiq

错误

AddEmployeesToRoomJob JID-da24b13f405b1ece1212bbd5 INFO: fail: 0.003     sec
2016-08-20T14:57:16.645Z 19456 TID-owmym5fbk WARN:     {"class":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper","wrapped"    :"AddEmployeesToRoomJob","queue":"default","args":    [{"job_class":"AddEmployeesToRoomJob","job_id":"0ba5bd30-e281-49a7-a93f-    6e50445183ac","queue_name":"default","priority":null,"arguments":    [{"_aj_globalid":"gid://dragonfly/Room/1"}],"locale":"en"}],"retry":true,"jid":"da24b13f405b1ece1212bbd5","created_at":1471704675.739077,"enqueued    _at":1471705036.6406531,"error_message":"Error while trying to     deserialize arguments: Couldn't find Room with     'id'=1","error_class":"ActiveJob::DeserializationError","Failed_at":14717    04675.946183,"retry_count":4,"retried_at":1471705036.644416}
2016-08-20T14:57:16.645Z 19456 TID-owmym5fbk WARN:     ActiveJob::DeserializationError: Error while trying to deserialize     arguments: Couldn't find Room with 'id'=1
2016-08-20T14:57:16.645Z 19456 TID-owmym5fbk WARN:     /Users/tamlyn/.rvm/gems/ruby-2.2.3/gems/activerecord-    5.0.0.1/lib/active_record/relation/finder_methods.rb:357:in     `raise_record_not_found_exception!'

我的工作
    class AddEmployeesToRoomJob< ApplicationJob
      queue_as:

def perform(room)
    employees = Employee.all
    if employees.length > 0
      employees.each do |employee|
        UserRoom.create(user: employee,room: room)
      end
    end
  end
end

我的想法
我不明白为什么它找不到我正在进入执行方法的房间.就好像它在作业的队列化/ JSON化中以某种方式丢失了该变量?

Sidekiq博士说

“不幸的是,这意味着如果在作业入队后但在调用perform方法之前删除[Room]记录,则异常处理会有所不同.”

他们建议一个解决方法,但我不知道这对我有什么帮助:

rescue_from ActiveJob::DeserializationError do |exception|
    # handle a deleted user record
end

在此先感谢您的帮助!

解决方法

我不认为将Room对象传递给Sidekiq工作者是个好主意.我总是传递数据库对象的主键,然后重新查询.试试这个.

AddEmployeesToRoomJob.perform_later room.id

def perform(room_id)
  room = Room.find(room_id)
  employees = Employee.all
    if employees.length > 0
      employees.each do |employee|
        UserRoom.create(user: employee,room: room)
      end
    end
  end
end

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...