【问题标题】:memcached as an Object store in RailsMemcached 作为 Rails 中的对象存储
【发布时间】:2010-08-20 14:04:19
【问题描述】:

我将 Memcached 用作我的 Rails 应用程序的对象存储,我在其中存储搜索结果,这些结果是 memcached 中的用户对象

现在,当我取出数据时,我得到了 Memcached Undefined Class/Module 错误。我在这个博客中找到了解决这个问题的方法

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

 before_filter :preload_models
  def preload_models
    Model1
    Model2
  end

建议事先预先加载模型。我想知道这个问题是否有更优雅的解决方案,使用预加载技术是否有任何缺点。

提前致谢

【问题讨论】:

    标签: ruby-on-rails memcached models eager-loading


    【解决方案1】:

    我也遇到了这个问题,我想我想出了一个很好的解决方案。

    您可以覆盖 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
    

    【讨论】:

    • 这个解决方案很棒,但仅限于活动记录模型。有时你会缓存非 AR 类,在这种情况下,我认为你必须求助于这个线程上的第一个解决方案。
    • @KonstantinGredeskoul 跳过 preload_models 部分
    【解决方案2】:

    今天遇到了这个问题,设法提出了一个更简洁的解决方案,应该适用于所有课程。

    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
    

    不知道为什么[MemCacheStore] 没有被调用是[MemCacheStore.const_missing] 方法并且一切都以正常的“Rails-y”方式被调用。但是,这应该效仿!

    干杯,

    克里斯

    【讨论】:

      猜你喜欢
      • 2018-12-09
      • 1970-01-01
      • 2011-11-05
      • 1970-01-01
      • 2013-12-30
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多