Keep Track of Cache and Invalidate

I am yet to try this but it is a suggestion open to criticism.

When caching it can be hard to keep track of where a model has caches and what the cache keys are labeled as.  There are some tricks which allow the definition of the cache key invalidate the cache.  For example if I cache a User I can put the cache key as “user.id/user.updated_at’ which will fall off the bottom of the stack (in memcached) and you never need to invalidate it.

There are times when there is no single value which represents the state of something you are caching, other than the state of each of those cached things.  Very technical I know.  Let me give you an example.

Say I have a model User, which has an association :has_one to the Car model.  The Car model has a Brand model associated with it.  Also the User has a couple of stats which relate to him/her, posts, time on site, friends, I don’t know… Something useful which is calculated on a different model.  Anyway, lets say there is a little description block which is sprinkled all throughout the website which contains the User name, Car name, model and Car Brand.  Possibly a picture from one of them.  This little description block is placed next to anything this user does, which could be all pages all over the place.  Good case for caching.

So how to handle invalidation?  Well you could use the User.updated_at and whenever an associated model is changed, update the updated_at on the User model.  This will work, and work well.  Until you have 20+ associations to the User and all those associations has more associated to them.  Why is it a problem?  Well you are probably caching those other associations in regard to the User model with the updated_at as a key also.  Whenever any model associated with a User is changed, the updated_at is changed.  Which makes every cache that is dependant on updated_at get forgotten about.  That could be a lot of invalidated caches which were perfectly valid.

So my solution is a bit more work but I think could be useful in a larger scenrio.  Anytime you create a cache for a Model you create an invalidate_cache class method in its Model.  The method takes an array of objects which represent the models which have changed.  Then in the method it has logic for invalidating any caches which involve it and the passed in models.  I will give this a try later in the week and post back here any issues.

Posted on June 8, 2009 at 7:26 pm by Jordan Carter · Permalink
In: Uncategorized · Tagged with: ,

Leave a Reply