Reputation: 5540
I want to user in a grails service a ehcache session scoped.
I managed to have a cache bean from this definition in config/resources.groovy
myCache(org.springframework.cache.ehcache.EhCacheFactoryBean) {
timeToIdle = 5000 // life span in seconds
timeToLive = 5000 // life span in seconds
}
But the object obtained from the factory is singleton scoped.
What is the best way to have a session scoped ehcache in a session scoped service?
Thank you
Upvotes: 1
Views: 1023
Reputation: 75671
You can't do it with Ehcache since the cache manager maintains the caches by name and there can only be one cache per name. You would need to use another cache implementation that either doesn't enforce unique names or doesn't use the name as the "key" in the cache manager.
EDIT: This approach works, but doesn't use the factory bean:
import java.util.concurrent.atomic.AtomicInteger
import net.sf.ehcache.Cache
import net.sf.ehcache.CacheManager
import net.sf.ehcache.store.MemoryStoreEvictionPolicy
import org.springframework.beans.factory.DisposableBean
import org.springframework.beans.factory.InitializingBean
class MyService implements InitializingBean, DisposableBean {
private static AtomicInteger counter = new AtomicInteger()
private Cache cache
private String cacheName
static scope = 'session'
void afterPropertiesSet() {
int maxElementsInMemory = 10000
int maxElementsOnDisk = 10000000
MemoryStoreEvictionPolicy memoryStoreEvictionPolicy = MemoryStoreEvictionPolicy.LRU
boolean overflowToDisk = true
boolean eternal = false
int timeToLive = 5000 // 120
int timeToIdle = 5000 // 120
boolean diskPersistent = false
int diskExpiryThreadIntervalSeconds = 120
int diskSpoolBufferSize = 0
cacheName = 'myservice-cache-' + counter.incrementAndGet()
cache = new Cache(cacheName, maxElementsInMemory, memoryStoreEvictionPolicy,
overflowToDisk, null, eternal, timeToLive, timeToIdle,
diskPersistent, diskExpiryThreadIntervalSeconds, null,
null, maxElementsOnDisk, diskSpoolBufferSize)
CacheManager.getInstance().addCache cache
}
void destroy() {
cache.removeAll()
CacheManager.getInstance().removeCache(cacheName)
}
}
Since the service is session-scoped the cache doesn't have to be since it's controlled entirely by the service. By implementing InitializingBean
you can create the cache when the session starts, and remove it when the session ends by implementing DisposableBean
. Feel free to use a different cache name approach; this one just guarantees that they're unique. Also I've enumerated the cache constructor values based on the defaults in EhCacheFactoryBean
but those could be inlined.
Upvotes: 2