ruby-on-rails - 使用Sidekiq进行事件作业并获取ActiveJob::DeserializationError

标签 ruby-on-rails queue sidekiq rails-activejob

我正在尝试使用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!'

我的工作
类AddEmployeesToRoomJob 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

我的想法
我不明白为什么找不到我要传递给perform方法的房间。好像它在工作的队列化/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

关于ruby-on-rails - 使用Sidekiq进行事件作业并获取ActiveJob::DeserializationError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39055708/

相关文章:

ruby-on-rails - 有没有办法在 Rails-API 中使用 MiniProfiler?

ruby-on-rails - 使用 Homebrew 软件安装了 elasticsearch,但找不到配置文件

ruby-on-rails - `only:` 处的 `before_action` 在 Rails 中如何工作?

java - 实现一个队列,您可以在特定位置插入元素,同时在恒定时间内入队/出队?

ruby-on-rails - 名称错误 : uninitialized constant MyJob ActiveJob and Sidekiq

ruby-on-rails - 提交所有操作后,rails Transactions block 是否退出?

php - laravel 应用程序中的 beanstalkd 驱动程序配置错误

spring - Spring JavaMailSender:使其异步且持久

ruby-on-rails - 删除Sidekiq中的所有计划任务

ruby-on-rails - Sidekiq 工作人员无法写入数据库或日志文件