EHC ❯ RefreshAheadCache fails to remove it support cache when removed from CacheManager
-
Bug
-
Status: New
-
2 Major
-
Resolution:
-
ehcache,ehcache-core
-
-
drb
-
Reporter: wlfshmn
-
April 15, 2015
-
0
-
Watchers: 1
-
April 15, 2015
-
Description
Removing a RefreshAheadCache from the cache manager fails to remove the supprot cache. The localDispose method appears to not use the support caches name when attempting to remove the support cache.
The following code demonstrates the issue:
import net.sf.ehcache.*;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.constructs.blocking.CacheEntryFactory;
import net.sf.ehcache.constructs.blocking.SelfPopulatingCache;
import net.sf.ehcache.constructs.refreshahead.RefreshAheadCache;
import net.sf.ehcache.constructs.refreshahead.RefreshAheadCacheConfiguration;
import net.sf.ehcache.loader.CacheLoader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class RefreshAheadCacheRemovalMinimalTestCase_2_10_0 {
private Ehcache cache;
public static void main(String[] args) {
RefreshAheadCacheRemovalMinimalTestCase_2_10_0 main = new RefreshAheadCacheRemovalMinimalTestCase_2_10_0();
main.init();
main.init();
main.init();
}
private synchronized void init() {
final CacheManager cacheManager = CacheManager.getInstance();
final CacheConfiguration cacheConfiguration = new CacheConfiguration()
.name(String.format("%s", this.getClass().getName() + UUID.randomUUID()))
.maxEntriesLocalHeap(1);
final Cache cache = new Cache(cacheConfiguration);
cacheManager.addCache(cache);
final CacheEntryFactory cacheEntryFactory = new CacheEntryFactory() {
@Override
public Object createEntry(final Object key) throws Exception {
return System.currentTimeMillis();
}
};
final SelfPopulatingCache selfPopulatingCache = new SelfPopulatingCache(cache, cacheEntryFactory);
final RefreshAheadCacheConfiguration refreshConfig = new RefreshAheadCacheConfiguration()
.maximumRefreshBacklogItems(10)
.build();
final RefreshAheadCache refreshAheadCache = new RefreshAheadCache(selfPopulatingCache, refreshConfig);
cache.registerCacheLoader(new CacheLoaderAdapter(cacheEntryFactory));
cacheManager.replaceCacheWithDecoratedCache(cache, refreshAheadCache);
// save old cache in order for us to know what to dispose of
final Ehcache oldCache = this.cache;
// replace user visible cache
this.cache = refreshAheadCache;
// remove old caches
if (oldCache != null) {
cacheManager.removeCache(oldCache.getName());
/*
// improper hack to compensate for RefreshAheadCache failing to dispose of it's support cache.
cacheManager.removeCache(String.format("%s_net.sf.ehcache.constructs.refreshahead.RefreshAheadCache_refreshAheadSupport", oldCache.getName()));
*/
}
System.out.printf("after reinitializing cachemanager contains %d caches.%n", cacheManager.getCacheNames().length);
for (String cacheName : cacheManager.getCacheNames()) {
System.out.println("\t" + cacheName);
}
}
private static class CacheLoaderAdapter implements CacheLoader {
private final CacheEntryFactory factory;
public CacheLoaderAdapter(final CacheEntryFactory factory) {
this.factory = factory;
}
@Override
public Object load(final Object key) throws CacheException {
return loadInternal(key);
}
@Override
public Map loadAll(final Collection keys) {
return loadAllInternal(keys);
}
@Override
public Object load(final Object key, final Object argument) {
return loadInternal(key);
}
@Override
public Map loadAll(final Collection keys, final Object argument) {
return loadAllInternal(keys);
}
@Override
public String getName() {
return this.getClass().getName();
}
@Override
public CacheLoader clone(final Ehcache cache) throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
@Override
public void init() {
}
@Override
public void dispose() throws CacheException {
}
@Override
public Status getStatus() {
return Status.STATUS_ALIVE;
}
private Object loadInternal(final Object key) throws CacheException {
try {
return factory.createEntry(key);
} catch (final Exception e) {
throw new CacheException(e);
}
}
private Map loadAllInternal(final Collection keys) {
final Map<Object, Object> results = new HashMap<Object, Object>(keys.size());
for (final Object key : keys) {
try {
final Object object = loadInternal(key);
results.put(key, object);
} catch (final CacheException e) {
e.printStackTrace();
}
}
return results;
}
}
}