MongoDB Mongoid 升级之后 Mongoid::QueryCache::Middleware 问题

easyhappy · 2014年03月04日 · 4038 次阅读

前言

由于最近在将项目升级到Rails, 顺便将Mongoid从也从3.1.4 升到3.1.6, 至于为什么, 可以点击这里 升级Mongoid 的一些配置 被除掉了, IndentityMap 就是之一, 然后官方给出的替代方式是使用Query::Cache Middleware.

在配置文件添加config.middleware.use(Mongoid::QueryCache::Middleware);

问题来了

假如 我执行下面的操作:

def index
  @users = UserMongo.all
end

然后其他的地方

if @users.present?       #----> 标记A
   ...其他操作
   @users.each do |p|    #-----> 标记B
       ....
   end
end

执行的'标记B'的时候, 会抛出异常

QUERY CACHE  database=tianji collection=users selector={}
TypeError: no implicit conversion of String into Integer
from /home/andy/Documents/mongoid/lib/mongoid/factory.rb:40:in `[]'

问题追踪

通过pry 追踪源码

module Mongoid
  module QueryCache
    module Cacheable
      def with_cache
        return yield unless QueryCache.enabled?
        return yield if system_collection?
        key = cache_key
        if QueryCache.cache_table.has_key?(key)
          instrument(key) { QueryCache.cache_table[key] }
        else
          value = yield
          QueryCache.cache_table[key] = value
        end
      end
  end
end

发现 在执行'标记A' @users.present?, QueryCache.cache_table[key] 的值已经被设置上了

puts QueryCache.cache_table -->
{["tianji", "users", {}]=>{"_id"=>158}}

然后在 执行'标记B’ 的时候 其实 是对 'A'的结果 进行遍历, 所以 就会报错.

我的观点:

我认为 这是 QueryCache的一个bug, 没有很好区分好 QueryCache.cache_table 的 key。

补充一下 key的选取是这样子的:

def cache_key
    [ operation.database, operation.collection, operation.selector ]
end

SOS

大家在升级 Mongoid的过程中, 有没有遇到同样的问题; 实在不行, 我可能会先覆盖部分Mongoid源码.

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册