1

My application has a couple of services that make external calls via httpClient (GET and POST) that are unlikely to change in months, but they are slow; making my application even slower. Clarification: this is NOT about caching GORM/hibernate/queries to my db.

How can I cache these methods (persistence on disk gets bonus points...) in grails 2.1.0?

I have installed grails-cache-plugin but it doesn't seem to be working, or i configured it wrong (very hard to do since there are 2-5 lines to add only, but i've managed to do it in the past)

I also tried setting up an nginx proxy cache in front of my app, but when i submit one of my forms with slight changes, I get the first submission as result.

Any suggestions/ideas will be greatly appreciated.

EDIT: Current solution (based on Marcin's answer)

My config.groovy: (the caching part only)

//caching
grails.cache.enabled = true
grails.cache.clearAtStartup = false

grails.cache.config = {
    defaults {
        timeToIdleSeconds 3600
        timeToLiveSeconds 2629740
        maxElementsInMemory 1
        eternal false
        overflowToDisk true
        memoryStoreEvictionPolicy 'LRU'
    }

    diskStore {
        path 'cache'
    }

    cache {
        name 'scoring'
    }
    cache {
        name 'query'
    }
}

The important parts are:

  • do not clear at startup (grails.cache.clearAtStartup = false)
  • overflowToDisk=true persists all results over maxElementsInMemory
  • maxElementsInMemory=1 reduced number of elements in memory
  • 'diskStore' should be writable by the user running the app.
CoderX
  • 120
  • 9

3 Answers3

4

Grails Cache Plugin works quite well for me under Grails 2.3.11. Documentation is pretty neat, but just to show you a draft...

I use the following settings in Config.groovy:

grails.cache.enabled = true
grails.cache.clearAtStartup = true

grails.cache.config = {
    defaults {
        maxElementsInMemory 10000
        overflowToDisk false
        maxElementsOnDisk 0
        eternal true
        timeToLiveSeconds 0
    }
    cache {
        name 'somecache'
    }
}

Then, in the service I use something like:

@Cacheable(value = 'somecache', key = '#p0.id.toString().concat(#p1)')
def serviceMethod(Domain d, String s) {
    // ...
}

Notice the somecache part is reused. Also, it was important to use String as key in my case. That's why I used toString() on id.

The plugin can be also set up to use disk storage, but I don't use it.

If it doesn't help, please provide more details on your issue.

Marcin Świerczyński
  • 2,096
  • 21
  • 29
  • Thanks for the answer, this is how i started, but i still need to persist the cache data. Also do you have a custom class for the key generation or the default will suffice? – CoderX Nov 18 '14 at 16:42
  • The default was enough. Considering persisting... I use [Ehcache Cache Plugin](http://grails.org/plugin/cache-ehcache) together with Cache and it actually **provides** persisting. For example, `overflowToDisk` and `maxElementsOnDisk` settings are described [here](http://grails-plugins.github.io/grails-cache-ehcache/guide/usage.html). I'm quite sure this is the way to go. Please, let me know if I can help you in any way. Tx! – Marcin Świerczyński Nov 18 '14 at 18:57
  • Thanks Marcin, this set me up in the right direction. I edited my question with the current solution with persistance, but I might have to refine it later. – CoderX Nov 18 '14 at 21:56
  • Tx! Glad I could help! – Marcin Świerczyński Nov 18 '14 at 22:37
0

This may not help, but if you upgrade the application to Grails 2.4.x you can use the @Memoize annotation. This will automagically cache the results of each method call based upon the arguments passed into it.

George Smith
  • 857
  • 2
  • 10
  • 22
  • Eventually my idea is to do the move to 2.4, but after seeing my boss fight with other update (2.1 -> 2.4) I decided to leave it for when I have LOTS of time. Thanks for the idea though. – CoderX Nov 17 '14 at 19:40
0

In order to store this "almost static" information you could use Memcached or Redis as a cache system. (There are many others)

This two cache systems allows you to store key-value data (in your case something like this "key_GET": JSON,XML,MAP,String ).

Here is a related post: Memcached vs. Redis?

Regards.

Community
  • 1
  • 1
Bruno C
  • 13
  • 3