延迟作业对象没有正确反序列化

问题描述:

我很难相信我所看到的,但它肯定看起来像DJ无法正确反序列化一个对象。我看着mongo中的DJ记录,并且在YAML中看到该对象已设置其text字段,但是当代码运行时,text字段未设置。下面是一些最起码的摄制代码:延迟作业对象没有正确反序列化

class Board 
    include Mongoid::Document 
    field :text, type: String 

    def process_text_field 
     if not self.text 
      raise "Text field is blank" 
     end 
     # Text field gets processed 
    end 
end 

# in a controller 
def start_doing_something_slow 
    board = Board.find(params[:id]) 
    board.text = "Text field is set" 
    board.save! 
    raise "Text disappeared!" unless board.text 
    board.delay.process_text_field 
    render json: {:result=>'ok'} 
end 

我调用与浏览器的控制方法,以及直接检查DJ纪录蒙戈。我在YAML中看到Board对象的text字段已正确设置。但是当它在DJ中执行时,会引起Text field is blank例外。

不知何故,它不正确反序列化对象。

好吧,这花了我一个星期才弄清楚,所以我在这里发布它来帮助其他陷入这个陷阱的人。原来这是delayed_job_mongoid中的known bug。它有一个简单的修复程序,在错误报告中列出了10个月。

如果您在mongoid中使用身份映射,则该身份映射将作为数据库的进程内缓存层。对于正常的Web请求,缓存会在每个请求之间被清除,所以您的控制器方法不会使用对象的陈旧版本。但是,delayed_job_mongoid没有清除没有这个补丁的作业之间的缓存(我只是放在一起):https://github.com/collectiveidea/delayed_job_mongoid/pull/38

结果是您的延迟作业有时使用旧版本的对象,这取决于它们之前运行的是什么真正奇怪的神秘故障,除非你明白发生了什么,否则这些故障是非常难以追查的。