smartly_caches, smarter than ever
1
Please note that the problem introduced here and the technique proposed to
solve it can be applied for any RESTful web application. The post might be
using Rails terminologies/expressions/code only for demonstration.
Consider the following scenario: You access a resource namely "item" via a
simple restful get request (items/1). You want to cache the response of that
request, and expire that cache if any model (database) changes occurs to that
specific item (with id =1).
The straight forward (ugly) solution is to expire the cached response
explicitly in other actions of the controller (ie. Update and Destroy).
Rails sweepers aim to simplify some of the coupling between controller code and
cache expiry code and spare you from using the expire_xxx methods directly in
the actions of your controller. Typically you need one sweeper per controller.
However as your code grows, this becomes very tedious and hard to maintain as
well.
It would be great if we can no more worry about the expiry code at all, and let
a smart caching server (like memcached) do auto expiry using appropriate (LRU?)
techniques.
This leaves us with the problem of getting an old cached response if the
resource (db record) bound to that request has actually changed. The solution
is model versioning. We can version our (Item) model and update the version of
the corresponding record on each resource (db) update. One possible
implementation for this may be done by adding a "version" column to the "items"
table and update it as appropriate. A smarter way is to keep the db untouched
and save the version in your cache store with the pair (model name, id) as the
key (for example Item_1) and the version is the value. Enough talk, here’s a
piece of code that illustrates this…
And then of course we must have an observer for the Item model that updates
the version of each item on various updates; so that when a specific item gets
updated (in our example item 1) the value of the key "Item_1" is updated in the
cache store allowing cache_response to behave correctly, runs the action and
store the new response for the updated item. What I need to do is wrap all this
code in a plugin, namely smartly_caches that should be used as a replacement to
Rails’ caches_action so that you don’t have to write any of the above code in
your controller, nor do you have to write the model observer. A smart
implementation of cache_response should be included in the plugin that would
save a memcache access whenever possible by using http cache as a first level
cache. Ideally all you need to do is add the following line to your controller:
Yet, it would be even better if we can selectively update versions of
associated members of models. For example we may to want to expire the show
page of item 1 (items/1) not only when the item 1 changes, but also when the
price (which is a different model associated with the Item) of item 1 changes.
So, we want to be able to write something as easy as:
Smarter than ever, isn’t it?
Comments
Post a Comment
eSpace podcast Prodcast
Archive
- August 2010
- July 2010
- June 2010
- April 2010
- March 2010
- November 2009
- October 2009
- September 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- November 2008
- October 2008
- September 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- January 2008
- April 2007
- March 2007
Latest Comments
- SpectraMind Commented on Egypt Wins UK's National Outsourcing Association Award
- Rofaida Awad Commented on Go Egypt Go!
- Different Mike Commented on Only idiots change their iPhone root password!
- Mike Commented on Only idiots change their iPhone root password!
- smile Commented on Only idiots change their iPhone root password!

