Caching application data

Hi~

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)

Alon.

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 = {}   end

  def get(key)     self.cache[key.to_s.downcase]   end

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

  def delete (key)     self.cache.delete(key.to_s.downcase)   end

  def reset     self.cache.clear   end

end

c = Cache.instance puts c.get(:foo) c.put(:foo, "hello") 3.times { puts c.get(:foo) } c.delete(: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 process.

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.

Cheers-

-- Ezra Zygmuntowicz-- Lead Rails Evangelist -- ez@engineyard.com -- Engine Yard, Serious Rails Hosting -- (866) 518-YARD (9273)