Search code examples
grailsgrails-plugin

Controller action caching does not appear to work using Grails Cache Plugin


Grails Version: 3.0.9

Groovy Version: 2.4.5

JVM Version: 1.8.0_60

I am using the Grails cache plugin

http://grails-plugins.github.io/grails-cache/3.0.1/guide/index.html

And I have had some success caching service methods such as:

@Transactional
class EventCategoryService {

    @Cacheable('eventCategory')
    def findAllSports() {
        def sportCategories
        log.info('called EventCategoryService.findAllSports')
        sportCategories = EventCategory.findAllByParentCategoryName("Sport", [sort: "order"])
    }
}

Once the cache is created, I no longer see 'called EventCategoryService.findAllSports' appear in the logs on subsequent calls as expected.

However, the plugin states in a section named 'Controller action caching' that 'you can also cache responses for web requests using the same annotations'.

@Cacheable('eventCategory')
def index(IndexCommand command) {

    command.init()

    log.info('called frontend:index')

    render (view: "index", model: [command: command, distances: distances])
}

Unfortunately, each call I see 'called frontend:index' appear in the logs and some rudimentary timing confirms that there is no increase in speed during the call.

Am I missing a trick? I am not able to find the solution so any help would be greatly appreciated.

I'll include the command object should this have any bearing on the caching?

class IndexCommand {

    def searchService
    def eventCategoryService

    int max
    int offset
    String search
    java.util.Date queryStartDate = new Date()
    java.util.Date queryEndDate = new Date().plus(365)
    def sportCategories

    def results

    def benchmark = { closure ->
        def start = System.currentTimeMillis()
        closure.call()
        def now = System.currentTimeMillis()
        now - start
    }

    def init() {

        if (!max) max = 6
        if (!offset) offset = 0

        def duration = benchmark {
            results = searchService.advancedSearchWithPagedResults(
                    max,
                    offset,
                    search,
                    queryStartDate,
                    queryEndDate)
        }
        log.info("searchService.advancedSearchWithPagedResults took ${duration} ms" )

        duration = benchmark {
            sportCategories = eventCategoryService.findAllSports()
        }
        log.info("EventCategory.findAllByParentCategoryName took ${duration} ms" )
    }
}

Solution

  • You are passing IndexCommand command in your action so each time you call the action you are passing different object of IndexCommand. And the values are cached but you have to pass the same object to get the value from cache.

    So instead of passing the whole object, you can pass the required field of object and create the object in the action instead.

    Hope this helps.

    Thanks