简体   繁体   English

memcached作为Rails中的Object存储

[英]memcached as an Object store in Rails

I am using Memcached as an Object Store with my Rails application where I store search results which are User objects in memcached 我在我的Rails应用程序中使用Memcached作为Object Store,我在其中存储了memcached中User对象的搜索结果

Now when I fetch the data out I get the Memcached Undefined Class/Module Error. 现在,当我获取数据时,我得到了Memcached Undefined Class / Module Error。 I found a solution for this problem in this blog 我在这个博客中找到了解决这个问题的方法

http://www.philsergi.com/2007/06/rails-memcached-undefinded-classmodule.html http://www.philsergi.com/2007/06/rails-memcached-undefinded-classmodule.html

 before_filter :preload_models
  def preload_models
    Model1
    Model2
  end

which recommends pre-loading the models before hand. 建议事先预装模型。 I would like to know if there is a more elegant solution to this problem and are there any drawbacks in using the preloading technique. 我想知道是否有一个更优雅的解决方案来解决这个问题,并且使用预加载技术有任何缺点。

Thanks in advance 提前致谢

I had this problem as well and I think i came up with a nice solution. 我也有这个问题,我想我想出了一个很好的解决方案。

You can overwrite the fetch method and rescue the error and load the right constants. 您可以覆盖fetch方法并挽救错误并加载正确的常量。

module ActiveSupport
  module Cache
    class MemCacheStore
      # Fetching the entry from memcached
      # For some reason sometimes the classes are undefined
      #   First rescue: trying to constantize the class and try again.
      #   Second rescue, reload all the models
      #   Else raise the exception
      def fetch(key, options = {})
        retries = 2 
        begin
          super
        rescue ArgumentError, NameError => exc         
          if retries == 2
            if exc.message.match /undefined class\/module (.+)$/
              $1.constantize
            end
            retries -= 1
            retry          
          elsif retries == 1
            retries -= 1
            preload_models
            retry
          else 
            raise exc
          end
        end
      end

      private

      # There are errors sometimes like: undefined class module ClassName.
      # With this method we re-load every model
      def preload_models     
        #we need to reference the classes here so if coming from cache Marshal.load will find them     
        ActiveRecord::Base.connection.tables.each do |model|       
          begin       
            "#{model.classify}".constantize 
          rescue Exception       
          end     
        end       
      end
    end
  end
end

Ran across this today, managed to come up with a more terse solution that should work for all classes. 今天就这样,设法提出了一个应该适用于所有课程的更简洁的解决方案。

Rails.cache.instance_eval do
  def fetch(key, options = {}, rescue_and_require=true)
    super(key, options)

  rescue ArgumentError => ex
    if rescue_and_require && /^undefined class\/module (.+?)$/ =~ ex.message
      self.class.const_missing($1)
      fetch(key, options, false)
    else
      raise ex
    end
  end
end

Not sure why [MemCacheStore] is not having is [MemCacheStore.const_missing] method called and everything getting called in the normal “Rails-y” way. 不确定为什么[MemCacheStore]没有调用[MemCacheStore.const_missing]方法,所有内容都以正常的“Rails-y”方式调用。 But, this should emulate that! 但是,这应该效仿!

Cheers, 干杯,

Chris 克里斯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM