我使用来自infinispan 8.2.6.Final的树缓存。我有下一个服务:
zip
Aspect @MCacheable通过public class TestService {
public static final String FIRST_CACHE = "firstCache";
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@MCacheable(value = FIRST_CACHE, key = "/#{id}/first")
public Object putInFirstCache(String id, String data) {
log.info("putInFirstCache");
return data;
}
@MCacheable(value = FIRST_CACHE, key = "/#{id}/second")
public Object putInSecondCache(String id, String data) {
log.info("putInSecondCache");
return data;
}
@MCacheEvict(value = FIRST_CACHE, key = "/#{id}")
public void evictFromCache(String id) {
log.info("evictFromCache");
}
}
Aspect @MCacheEvict通过treeCache.put(fqn, "data", result);
方面的值是hashMap中TreeCache的关键。
所以,我为这方面写了一个简单的测试:
treeCache.removeNode(fqn);
缓存配置为:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CacheTestConfig.class, loader = AnnotationConfigContextLoader.class)
public class AspectTest {
@Autowired
private TestService testService;
@Autowired
private TreeCache treeCache;
@Test
public void testMCacheEvicts() throws InterruptedException {
String id = UUID.randomUUID().toString();
String data = System.currentTimeMillis() + "";
testService.putInFirstCache(id, data);
Thread.sleep(2000);
testService.putInSecondCache(id, data);
cacheDump(treeCache);
Thread.sleep(3500);
//miss here
cacheDump(treeCache);
assertEquals(null, treeCacheContainer.get(TestService.FIRST_CACHE).get(id + "/first", "data"));
testService.evictFromCache(id);
cacheDump(treeCache);
assertEquals(null, treeCacheContainer.get(TestService.FIRST_CACHE).get(id + "/second", "data"));
}
private void cacheDump(TreeCache<String, Object> treeCache) {
StringBuilder sb = new StringBuilder("{\r\n");
for (Map.Entry<?, ?> entry : treeCache.getCache().entrySet()) {
sb.append("[ ").append(entry.getKey()).append(",").append(entry.getValue()).append(" ]\r\n");
}
sb.append("}\r\n");
System.out.println("Cache dump: " + sb.toString());
}
}
这个测试的结果非常奇怪:
@Bean
public DefaultCacheManager cacheManager() {
org.infinispan.configuration.cache.Configuration cfg = new ConfigurationBuilder()
.jmxStatistics().enable()
.eviction().strategy(EvictionStrategy.LRU).type(EvictionType.COUNT).size(5000)
.expiration().wakeUpInterval(2, TimeUnit.SECONDS).lifespan(5, TimeUnit.SECONDS).maxIdle(100, TimeUnit.SECONDS)
.invocationBatching().enable()
.build();
return new DefaultCacheManager(cfg, true);
}
谁知道为什么infinispan过期缓存的根节点,如果孩子存在?
答案 0 :(得分:1)
简单的答案是,因为TreeCache
实现中没有任何内容可以处理到期。
底层缓存单独过期每个条目,TreeCache
必须触及每个父级的STRUCTURE
和DATA
条目,以修改子级以使其保持活动状态。或者,可能更容易实现,TreeCache
可以确保在父级到期时从缓存中删除所有子级。