use of org.infinispan.notifications.cachelistener.event.CacheEntriesEvictedEvent in project infinispan by infinispan.
the class CacheNotifierImplTest method testNotifyCacheEntriesEvicted.
public void testNotifyCacheEntriesEvicted() {
InternalCacheEntry ice = TestInternalCacheEntryFactory.create("k", "v");
n.notifyCacheEntriesEvicted(Collections.singleton(ice), null, null);
assertTrue(cl.isReceivedPost());
assertEquals(1, cl.getInvocationCount());
assertEquals(mockCache, cl.getEvents().get(0).getCache());
assertEquals(Event.Type.CACHE_ENTRY_EVICTED, cl.getEvents().get(0).getType());
Map<Object, Object> entries = ((CacheEntriesEvictedEvent) cl.getEvents().get(0)).getEntries();
Map.Entry<Object, Object> entry = entries.entrySet().iterator().next();
assertEquals("k", entry.getKey());
assertEquals("v", entry.getValue());
}
use of org.infinispan.notifications.cachelistener.event.CacheEntriesEvictedEvent in project infinispan by infinispan.
the class EvictionWithConcurrentOperationsTest method testScenario6.
/**
* ISPN-3048: a put triggers the eviction while another thread tries to read. the read occurs after the eviction
* listener is notified (if passivation is enabled, it is written to disk) and after the entry is removed from the
* map. however, a concurrent put happens at the same time before the get has time to load it from persistence. The
* get will occur after the put writes to persistence and before writes to data container
*/
public void testScenario6() throws Exception {
final Object key1 = new SameHashCodeKey("key1");
initializeKeyAndCheckData(key1, "v1");
final Object key2 = new SameHashCodeKey("key2");
final Latch readLatch = new Latch();
final Latch writeLatch = new Latch();
final Latch writeLatch2 = new Latch();
final AtomicBoolean firstWriter = new AtomicBoolean(false);
final AfterEntryWrappingInterceptor afterEntryWrappingInterceptor = new AfterEntryWrappingInterceptor().injectThis(cache);
afterEntryWrappingInterceptor.beforeGet = () -> readLatch.blockIfNeeded();
afterEntryWrappingInterceptor.afterPut = () -> {
if (!firstWriter.compareAndSet(false, true)) {
writeLatch2.blockIfNeeded();
}
};
final SyncEvictionListener evictionListener = new SyncEvictionListener() {
@CacheEntriesEvicted
@Override
public void evicted(CacheEntriesEvictedEvent event) {
if (event.getEntries().containsKey(key1)) {
writeLatch.blockIfNeeded();
}
}
};
cache.addListener(evictionListener);
// this will trigger the eviction of key1. key1 eviction will be blocked in the latch
readLatch.enable();
Future<Object> get;
Future<Object> put2;
try {
Future<Object> put = fork(() -> cache.put(key2, "v2"));
writeLatch.waitToBlock(30, TimeUnit.SECONDS);
// the eviction was trigger and the key is no longer in the map
get = fork(() -> cache.get(key1));
readLatch.waitToBlock(30, TimeUnit.SECONDS);
// Ensures the eviction is complete of key1
put.get(30, TimeUnit.SECONDS);
put2 = cache.putAsync(key1, "v3");
// wait until the 2nd put writes to persistence
writeLatch2.waitToBlock(30, TimeUnit.SECONDS);
} finally {
// let the get continue
readLatch.disable();
}
assertPossibleValues(key1, get.get(30, TimeUnit.SECONDS), "v1", "v3");
assertEquals("Wrong value for key " + key1 + " in put operation.", "v1", put2.get(30, TimeUnit.SECONDS));
assertInMemory(key1, "v3");
assertNotInMemory(key2, "v2");
}
use of org.infinispan.notifications.cachelistener.event.CacheEntriesEvictedEvent in project infinispan by infinispan.
the class EvictionWithConcurrentOperationsTest method testScenario4.
/**
* ISPN-3048: a put triggers the eviction while another thread tries to read. the read occurs after the eviction
* listener is notified (if passivation is enabled, it is written to disk) and after the entry is removed from the
* map. however, a concurrent read happens at the same time before the first has time to load it from persistence.
*/
public void testScenario4() throws Exception {
final Object key1 = new SameHashCodeKey("key1");
initializeKeyAndCheckData(key1, "v1");
final Object key2 = new SameHashCodeKey("key2");
final Latch readLatch = new Latch();
final Latch writeLatch = new Latch();
final AtomicBoolean firstGet = new AtomicBoolean(false);
final AfterEntryWrappingInterceptor afterEntryWrappingInterceptor = new AfterEntryWrappingInterceptor().injectThis(cache);
afterEntryWrappingInterceptor.beforeGet = () -> {
if (firstGet.compareAndSet(false, true)) {
readLatch.blockIfNeeded();
}
};
final SyncEvictionListener evictionListener = new SyncEvictionListener() {
@CacheEntriesEvicted
@Override
public void evicted(CacheEntriesEvictedEvent event) {
if (event.getEntries().containsKey(key1)) {
writeLatch.blockIfNeeded();
}
}
};
cache.addListener(evictionListener);
// this will trigger the eviction of key1. key1 eviction will be blocked in the latch
readLatch.enable();
Future<Object> put = fork(() -> cache.put(key2, "v2"));
writeLatch.waitToBlock(30, TimeUnit.SECONDS);
// the eviction was trigger and the key is no longer in the map
Future<Object> get = fork(() -> cache.get(key1));
readLatch.waitToBlock(30, TimeUnit.SECONDS);
// Ensures the eviction is complete of key1
put.get(30, TimeUnit.SECONDS);
// the first read is blocked. it has check the data container and it didn't found any value
// this second get should not block anywhere and it should fetch the value from persistence
assertEquals("Wrong value for key " + key1 + " in get operation.", "v1", cache.get(key1));
// let the second get continue
readLatch.disable();
assertEquals("Wrong value for key " + key1 + " in get operation.", "v1", get.get());
assertInMemory(key1, "v1");
assertNotInMemory(key2, "v2");
}
use of org.infinispan.notifications.cachelistener.event.CacheEntriesEvictedEvent in project infinispan by infinispan.
the class ManualEvictionWithSizeBasedAndConcurrentOperationsInPrimaryOwnerTest method testScenario4.
@Override
public void testScenario4() throws Exception {
final Object key1 = createSameHashCodeKey("key1");
initializeKeyAndCheckData(key1, "v1");
final Latch readLatch = new Latch();
final Latch writeLatch = new Latch();
final AtomicBoolean firstGet = new AtomicBoolean(false);
final AfterEntryWrappingInterceptor afterEntryWrappingInterceptor = new AfterEntryWrappingInterceptor().injectThis(cache);
afterEntryWrappingInterceptor.beforeGet = () -> {
if (firstGet.compareAndSet(false, true)) {
readLatch.blockIfNeeded();
}
};
final SyncEvictionListener evictionListener = new SyncEvictionListener() {
@CacheEntriesEvicted
@Override
public void evicted(CacheEntriesEvictedEvent event) {
if (event.getEntries().containsKey(key1)) {
writeLatch.blockIfNeeded();
}
}
};
cache.addListener(evictionListener);
// this will trigger the eviction of key1. key1 eviction will be blocked in the latch
readLatch.enable();
Future<Void> evict = evictWithFuture(key1);
writeLatch.waitToBlock(30, TimeUnit.SECONDS);
// the eviction was trigger and the key is no longer in the map
Future<Object> get = fork(() -> cache.get(key1));
readLatch.waitToBlock(30, TimeUnit.SECONDS);
// the first read is blocked. it has check the data container and it didn't found any value
// this second get should not block anywhere and it should fetch the value from persistence
assertEquals("Wrong value for key " + key1 + " in get operation.", "v1", cache.get(key1));
// let the eviction continue and wait for put
writeLatch.disable();
evict.get(30, TimeUnit.SECONDS);
// let the second get continue
readLatch.disable();
assertEquals("Wrong value for key " + key1 + " in get operation.", "v1", get.get(30, TimeUnit.SECONDS));
assertInMemory(key1, "v1");
}
Aggregations