Caching application data


Alon wrote:

Thanks catlady and Mark - very good suggestions and very appreciated.
Yes, singleton class is my preference actually, as suggested by Alex.
However, as I indicated in my last posting above, it doesn't seem to
work for me - the application works but it seems to be accessing the
database every single time for the data... I am probably doing something
wrong - I'll appreciate if somebody can see if it's something obvious
(short code snipet above)


The reason it wasn't working for you was because you weren't using a
singleton. Here's a very very simple singleton cache

require 'singleton'
class Cache
  include Singleton
  attr_reader :cache

  def initialize
    @cache = {}

  def get(key)

  def put(key, value)
    self.cache[key.to_s.downcase] = value

  def delete (key)

  def reset


c = Cache.instance
puts c.get(:foo)
c.put(:foo, "hello")
3.times { puts c.get(:foo) }
puts c.get(:foo)

If you run that you'll see when it does the loop it keeps returning
"hello" during the loop block. You can start getting clever with this
sort of thing and have the get method yield to a block if it can't find
the key, etc... Anyway, you get the idea.

Also, I don't know if you were running in development mode, but if you
were remember that AR models and controllers get reloaded ever single
time you make a request. So if you were expecting them to hold some sort
of state, apart from sessions in the controller, then that might be part
of your problem as well.

What I've outlined briefly above will hold state for the entire length
of your application. You can't kill a singleton until you kill the ruby

Anyway, hope this helps.

  While this may seem like the solution it is not. This will not work when you have multiple mongrels or fcgi's running for your app. Because each process will have its own copy of the singleton cache and your users are not garaunteed to always hit the same backend on each request> So the data in the cache will be inconsistent depending on which backend serves a certain request.

  The only way to do this correctly is to make it a drb server or just use memcached. The singleton cache stuff is great if you can garauntee that your app will never use more then one backend. But that will not scale.


-- Ezra Zygmuntowicz-- Lead Rails Evangelist
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)