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

时间:2013-04-23 17:19:52

标签: ruby-on-rails mongoid delayed-job

我很难相信我所看到的内容,但看起来DJ似乎无法正确地反序列化对象。我在mongo中查看DJ记录,我在YAML中看到该对象设置了text字段,但是当代码运行时,text字段未设置。这是一些最小的repro代码:

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

我用浏览器调用控制器方法,直接在mongo中检查DJ记录。我在YAML中看到Board对象正确设置了text字段。但是当它在DJ中执行时,它会引发Text field is blank异常。

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

1 个答案:

答案 0 :(得分:0)

嗯,这花了我一个星期才弄明白,所以我在这里张贴它来帮助陷入这个陷阱的其他人。事实证明这是delayed_job_mongoid中的known bug。它有一个简单的修复程序,在错误报告中列出了10个月。

如果您在mongoid中使用身份映射,则会出现问题,mongoid充当数据库的进程内缓存层。对于普通的Web请求,缓存在每个请求之间被清除,因此您的控制器方法不会使用对象的陈旧版本。但是如果没有这个补丁(我刚刚放在一起),delayed_job_mongoid不会清除作业之间的缓存:https://github.com/collectiveidea/delayed_job_mongoid/pull/38

结果是你的延迟工作有时会使用旧版本的对象,这取决于它们之前的运行情况,这会产生真正奇怪,神秘的故障,在你明白发生了什么之前很难追查。