The more recent version of Grails bundle a cute little Cache plugin that abstracts some of the Cache classes built into Spring 3.1. For the common use cases, you can simply make use of the @Cacheable annotation, and then make use of @CacheEvict when you need to clean things out. But this sample code demonstrates what to do when you need to evict several caches on a  single method call (for instance, because your changing the underlying data that may have been cached in several different calcs).

If you haven’t played with the Cache plugin before, here’s the skinny. Imagine you have a controller or service that performs a couple of  expensive operations on some shared dataset (you are going to refactor it into a service, right? :-). Here’s our skeleton placeholder:

package hubbub

import grails.plugin.cache.CacheEvict
import grails.plugin.cache.Cacheable
import java.util.concurrent.atomic.AtomicInteger

class CounterController {

    static defaultAction = "invalidatingMethod"

    static AtomicInteger counter = new AtomicInteger()

    @Cacheable("myCache")
    def expensiveMethod1() {

        // imagine the massive query from hell
        render "The latest value is ${counter.incrementAndGet()}"

    }

    @Cacheable("myOtherCache")
    def expensiveMethod2() {

        // imagine another massive query from hell
        render "The latest value is ${counter.incrementAndGet()}"

    }

    @CacheEvict(value=['myCache','myOtherCache'], allEntries=true)
    def invalidatingMethod() {
        // Something that would invalidate the cache... like a DB update
        render "The caches have been cleared"
    }
}

So our expensiveMethod1() and expensiveMethod2() have been marked @Cacheable. This means that Grails will intercept the calls, to these method, catch the return values and squirrel them off to the Cacheing infrastructure (in memory by default, so it will be reset on JVM restart).  Next time you call the method, Grails will returned the cached value (which saves you all that processing time).

In the scenario above, I’m using two different caches with two different names. I’m then using the annotation on invalidatingMethod() to clear an array of cache names in one hit! I’m not sure that’s covered in the current docs, I had to go hunting through the source. But at least it’s now google-able!

So, I’ve made my calls to each of my cached methods and confirmed they are returning cached values, for instance. :

  1. http://localhost:8080/hubbub/counter/expensiveMethod1 » The latest value is 1

  2. http://localhost:8080/hubbub/counter/expensiveMethod2 » The latest value is 2

  3. http://localhost:8080/hubbub/counter/expensiveMethod1 » The latest value is 1

  4. http://localhost:8080/hubbub/counter/expensiveMethod2 » The latest value is 2
    Imaging I then made method calls my invalidating method, and you can see how the cache is operating on the data (or copy and paste and try it at home for even more XP)

  5. http://localhost:8080/hubbub/counter/invalidatingMethod » The caches have been cleared

  6. http://localhost:8080/hubbub/counter/expensiveMethod1 » The latest value is 3

  7. http://localhost:8080/hubbub/counter/expensiveMethod2 » The latest value is 4

  8. http://localhost:8080/hubbub/counter/expensiveMethod1 » The latest value is 3

  9. http://localhost:8080/hubbub/counter/expensiveMethod2 » The latest value is 4
    So the first invocation to the cached method after the caches have been cleared repopulates the cache with the new value. Awesome!

This new lightweight caching is a very cool feature of Grails 2.x line and you should definitely checkout the docs to see way you can configure those caches to be persistent, overflow, etc.

Happy Caching!

(Regular shameless plugin: If you want to find out more about what’s new in Grails 2.x, make sure you checkout the MEAP of Grails in Action 2 which is now on the Manning Site and for which we’ll soon be releasing the plugins chapter which covers Caching and other goodness).