Monday, March 28, 2011

Cache-Money: Only use in Production?

I use the cache-money gem for transparent usage of Memcached. Using the supplied config file it is enabled on all modes (development, test, production). Is there a way to only activate cache-money in production mode?

It's not immediately clear how to do this, and it's a total pain dealing with caching in development mode.

From stackoverflow
  • In your initializer, skip initialization if you're running in development mode:

    unless 'development' == RAILS_ENV
      require 'cache_money'
      ....
    
    Matt Darby : I wish it was that easy. When cache-money isn't loaded, my indexed models fail to load: /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.0/lib/active_record/base.rb:1963:in `method_missing_without_paginate': undefined method `index' for # (NoMethodError)
    wesgarrison : Could you set the TTL option to zero in development? That way it wouldn't save the cached result?
  • Thanks to Obie Fernandez for a great offline hint: Stub out cache-money's #index method to do nothing. This provides a place for the #index statements in the models to go, and stops the error mentioned above.

    Here is my full cache_money.rb lib:

    if RAILS_ENV != 'development'
      require 'cache_money'
    
      config = YAML.load(IO.read(File.join(RAILS_ROOT, "config", "memcached.yml")))[RAILS_ENV]
      $memcache = MemCache.new(config)
      $memcache.servers = config['servers']
    
      $local = Cash::Local.new($memcache)
      $lock = Cash::Lock.new($memcache)
      $cache = Cash::Transactional.new($local, $lock)
    
      class ActiveRecord::Base
        is_cached :repository => $cache
      end
    else
      # If we're in development mode, we don't want to
      # deal with cacheing oddities, so let's overrite
      # cache-money's #index method to do nothing...
      class ActiveRecord::Base
        def self.index(*args)
        end
      end
    end
    
  • By turning off cache-money in test you can't know if its interfering with your code.

    I did this instead:

    require 'cache_money'
    require 'memcache'
    
    if RAILS_ENV == 'test'
      $memcache = Cash::Mock.new
    else
      config = YAML.load(IO.read(File.join(RAILS_ROOT, "config", "memcached.yml")))[RAILS_ENV]
      $memcache = MemCache.new(config)
      $memcache.servers = config['servers']
    end
    
    $local = Cash::Local.new($memcache)
    $lock = Cash::Lock.new($memcache)
    $cache = Cash::Transactional.new($local, $lock)
    
    class ActiveRecord::Base
      is_cached :repository => $cache
    end
    

0 comments:

Post a Comment