Monday, September 10, 2007

Declarative caching in the UI layer

In my recent post about the BestCrosswords.com architecture, I mentioned the fact that a fair amount of caching was taking place in the web UI layer. I'd like to expand on that.

The data consumed by web UI layer comes solely from the service layer. The services are injected into Tapestry components by Spring.

Let's take an example. If you look at the home page, you'll see that recently added crossword puzzles are displayed for different categories (e.g. American or British type puzzles). The Tapestry component responsible for outputting this bit of HTML uses the "constructor" (as in puzzle constructor) service, injected into the component at runtime. Since the component is located on a high traffic page, its performance needs to scale so hitting the service layer (and thus the database) on every requests is out of the question.

My first solution to this problem was to cache the service layer data in the component itself. It worked for a while but proved inflexible in the long run. For instance, depending on where a component was located (e.g. a high or low traffic page, etc), different caching strategies were needed.

My second solution (and the one I'm using now), was to configure caching proxies in Spring using Spring modules and Ehcache and inject those into the components instead of the real services. This way, I could decide to turn caching on or off depending on the specific needs of the component, without it being aware of anything.