7

RailsアプリケーションでMemcachedをオブジェクトストアとして使用しており、ユーザーオブジェクトである検索結果をmemcachedに保存しています。

データをフェッチすると、Memcachedの未定義のクラス/モジュールエラーが発生します。私はこのブログでこの問題の解決策を見つけました

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

 before_filter :preload_models
  def preload_models
    Model1
    Model2
  end

これは、事前にモデルを事前にロードすることをお勧めします。この問題に対してより洗練された解決策があるかどうか、およびプリロード手法を使用することに欠点があるかどうかを知りたいです。

前もって感謝します

4

2 に答える 2

8

私もこの問題を抱えていて、いい解決策を思いついたと思います。

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
于 2011-03-16T10:16:26.337 に答える
5

今日これに出くわし、すべてのクラスで機能するはずのより簡潔なソリューションを思い付くことができました。

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

メソッドが呼び出され、すべてが通常の「Rails-y」の方法で呼び出される理由[MemCacheStore]がわからない。[MemCacheStore.const_missing]しかし、これはそれをエミュレートする必要があります!

乾杯、

クリス

于 2012-01-24T11:35:21.370 に答える