7
\$\begingroup\$

I want to have fast cache in which I want to keep all my nomenclature data. I don't want to go with Memcached because I have to do serialize/de-serialize on each object which is slow.

So I choose to be less effective in memory and keep the cache in each server instance. I am sure I am doing it in the wrong way because the NoCache module - which skips my cache and hits the Rails cache is faster than mine.

Here is how it is initialized

$cache = Cache.new

Here is the example usage

property_types = $cache['PropertyType']

and here is the source

module DirectCache
  def init_cache
  end

  def reload_model(model_class)
    key = get_key(model_class)
    klass = key.constantize
    object = klass.scoped
    puts "Loading cache for #{key}..."
    if klass.respond_to?(:translates) and klass.translates?
      puts "  Adding translation in the model for #{klass}"
      object = object.includes(:translations)
      self.storage[key] = object.send("all")
    end
  end

  def [] class_name_or_object
    puts "Hiting cache for #{class_name_or_object}"
    key = get_key(class_name_or_object)
    reload_model(class_name_or_object) if self.storage[key].blank? or self.storage[key].empty?
    raise "#{key} is missing in the cache #{@cache.keys.join ', '}" unless key? key
    self.storage[key]
  end

  def init_cache
  end

end

module NoCache
  def reload_model(model_class)
    key = get_key(model_class)
    self.storage[key] = key.constantize
  end

  def [] class_name_or_object
    key = get_key(class_name_or_object)
    raise "#{key} is missing in the cache #{@cache.keys.join ', '}" unless key? key
    klass = self.storage[key]
    object = klass.scoped
    if klass.respond_to?(:translates) and klass.translates?
      puts "Adding translation in the model for #{klass}"
      object = object.includes(:translations)
    end
    object.send("all")
  end

  def init_cache
  end

end

class Cache
  include DirectCache
  #  include NoCache
  #  include OpenStructCache

  @@models = [
    PropertyFunction,
    PropertyCategoryLocation,
    ConstructionType,
 ....20 more ....
    ExposureType,
  ]

  cattr_reader :models

  def initialize
    @cache = {}
    begin
      init_cache
    rescue
      puts "missing tables"
    end
  end


  def storage
    @cache
  end

  # returns the the key - aways string
  def get_key class_name_or_record
    case class_name_or_record
    when Class
      key = class_name_or_record.to_s
    when String
      key = class_name_or_record
    else
      key = class_name_or_record.class.to_s
    end
    key
  end

  def key? class_name_or_object
    key = get_key(class_name_or_object)
    self.storage.keys.include? key
  end

end
\$\endgroup\$
  • \$\begingroup\$ what is you really question ? \$\endgroup\$ – shingara Jan 22 '11 at 14:31
  • \$\begingroup\$ I like your idea. Could you post this is StackOverflow instead? Would be interesting to solve this. \$\endgroup\$ – lulalala Oct 4 '13 at 6:30
3
\$\begingroup\$

The ActiveSupport::Cache is not mandatory in Memcached, there are a cache in memory if you use the :memory_store ( http://api.rubyonrails.org/classes/ActiveSupport/Cache/MemoryStore.html )

config.cache_store = :memory_store

Maybe can be a good start to implement your own Cache in memory

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.