JCacheConfiguration ignores eternal flag if configured using ehcache.xml
tarioch opened this issue · comments
As far as I'm able to tell, if I configure the cache with an ehcache.xml and have set the cache to be eternal, this is getting ignored as the constructor of JCacheConfiguration always sets up an expiry policy.
Looks like this was introduced when fixing #26
@tarioch You configure the Cache
in ehcache.xml, but still create a JCacheConfiguration
for it? I must be confused, can you provide a small (even pseudo code, doesn't need to make javac happy) example of how to problem is experienced?
Sure
I have an ehcache.xml and then do
Caching.getCachingProvider().getCacheManager().getCache("foo");
to retrieve the cache.
This triggers JCacheManager.refreshAllCaches() which does
allCaches.put(s, new JCache(this, new JCacheConfiguration(cache.getCacheConfiguration()), cache));
which then ends up in the failing code block.
Oh ok... so the issue is what the JCacheConfiguration
"pretends", but effectively the Cache
does honor it, right? I misunderstood that. That being said it still needs fixing! I'll make sure that happens... Thanks!
The issue I noticed is that, JCache.getValue() starts triggering a remove as it is actually reading this generated JCache config.
@tarioch I'll try to put a test case together to reproduce this... I seem to see we'll expose the TTI & TTL values, but these may well be set in your config (along with the eternal flag), so that these get picked up, rather than them being 0?
Line 843-846 in net.sf.ehcache.config.CacheConfiguration
(ehcache 2.8.3):
public final void setEternal(boolean eternal) {
checkDynamicChange();
isEternalValueConflictingWithTTIOrTTL(eternal, getTimeToLiveSeconds(), getTimeToIdleSeconds());
this.eternal = eternal;
if (eternal) {
setTimeToIdleSeconds(0);
setTimeToLiveSeconds(0);
}
}
If eternal
is true
, set timeToIdleSeconds
and timeToLiveSeconds
to 0
.
Line 93-108 in org.ehcache.jcache.JCacheConfiguration
(ehcache-jcache 1.0.1):
expiryPolicy = new ExpiryPolicy() {
@Override
public Duration getExpiryForCreation() {
return new Duration(TimeUnit.SECONDS, cacheConfiguration.getTimeToLiveSeconds());
}
@Override
public Duration getExpiryForAccess() {
return new Duration(TimeUnit.SECONDS, cacheConfiguration.getTimeToLiveSeconds());
}
@Override
public Duration getExpiryForUpdate() {
return getExpiryForCreation();
}
};
If eternal
is true
, the value of exipryForCreation
and expiryForAccess
will be 0
seconds duration.
Line 138-141 in org.ehcache.jcache.JCache
(ehcache-jcache 1.0.1):
private Element getElement(final K key) {
final Element element = ehcache.get(key);
if (element == null)
return null;
final Duration expiryForUpdate = cfg.getExpiryPolicy().getExpiryForAccess();
if(expiryForUpdate != null && expiryForUpdate.isZero()) {
ehcache.removeElement(element);
}
return element;
}
If the expireForAccess
is zero, the cached element will be removed when call JCache#get(K key)
. So, if you configure eternal="true"
in ehcache.xml
, the cache will be expired immediately when you call get(K key)
.
Add these codes in org.ehcache.jcache.JCacheConfiguration
may be fix it:
if(cacheConfiguration.isEternal()){
expiryPolicyFactory = EternalExpiryPolicy.factoryOf();
expiryPolicy = expiryPolicyFactory.create();
}else{
expiryPolicyFactory = null;
expiryPolicy = new ExpiryPolicy(){
//...
}
}
Any reason this has not been fixed? The change is pretty simple, and presently its not possible to configure an eternal cache via ehcache.xml because of this. Unsure about the expiryPolicyFactory = null;
in example above, but this seems to resolve the problem for me:
if (cacheConfiguration.isEternal()) {
expiryPolicy = EternalExpiryPolicy.factoryOf().create();
}
else {
expiryPolicy = new ExpiryPolicy()
{
@Override
public Duration getExpiryForCreation() {
return new Duration(TimeUnit.SECONDS, cacheConfiguration.getTimeToLiveSeconds());
}
@Override
public Duration getExpiryForAccess() {
return new Duration(TimeUnit.SECONDS, cacheConfiguration.getTimeToLiveSeconds());
}
@Override
public Duration getExpiryForUpdate() {
return getExpiryForCreation();
}
};
}
expiryPolicyFactory = new FactoryBuilder.SingletonFactory<ExpiryPolicy>(expiryPolicy);
Sorry for noise above, sometimes github linking is a bit of PITA
Sorry, my bad. Remained assigned to me, but I was off on vacation. Back now though.
I'll get back to you. Did you sign the contributor agreement already?
See here: https://github.com/ehcache/ehcache3/wiki#contributor-agreement
Ah the project is alive.. yay. Will sent over signed legal mumbo jumbo shortly.
Cool! Thanks... Now, that being said, the project is slow moving though. I have to be honest with you: all our efforts are going into Ehcache3, this wrapper was a temporary solution for 2.x users. But all (including features that were only "proprietary" ones in the 2.x line, e.g. Offheap) go into the new dev line. Here: https://github.com/ehcache/ehcache3
@alexsnaps understood, and we'll consume ehcache3 once it stabilizes, but until then we are moving to use javax.cache api to allow us to switch the backend, so having the adapter for ehcache2 is helping us move forward while ehcache3 becomes more realistic for usage.