use of org.cache2k.event.CacheEntryUpdatedListener in project cache2k by cache2k.
the class ListenerTest method manyAsyncUpdateListenerCalled.
/**
* Check that we do not miss events.
*/
@Test(timeout = TestingParameters.MAX_FINISH_WAIT_MILLIS)
public void manyAsyncUpdateListenerCalled() {
final AtomicInteger _callCount = new AtomicInteger();
final ConcurrentMap<Integer, Integer> _seenValues = new ConcurrentHashMap<Integer, Integer>();
Cache<Integer, Integer> c = target.cache(new CacheRule.Specialization<Integer, Integer>() {
@Override
public void extend(final Cache2kBuilder<Integer, Integer> b) {
b.addAsyncListener(new CacheEntryUpdatedListener<Integer, Integer>() {
@Override
public void onEntryUpdated(final Cache<Integer, Integer> cache, final CacheEntry<Integer, Integer> currentEntry, final CacheEntry<Integer, Integer> entryWithNewData) {
_seenValues.put(entryWithNewData.getValue(), entryWithNewData.getValue());
_callCount.incrementAndGet();
}
});
}
});
c.put(1, 2);
assertEquals(0, _callCount.get());
final int _UPDATE_COUNT = 123;
for (int i = 0; i < _UPDATE_COUNT; i++) {
c.put(1, i);
}
ConcurrencyHelper.await(new Condition() {
@Override
public boolean check() throws Exception {
return _callCount.get() == _UPDATE_COUNT;
}
});
assertEquals("Event dispatching is using copied events", 123, _seenValues.size());
}
use of org.cache2k.event.CacheEntryUpdatedListener in project cache2k by cache2k.
the class ListenerTest method asyncUpdateListenerCalled.
/**
* If the listener is not executed in separate thread, this would block
*/
@Test(timeout = TestingParameters.MAX_FINISH_WAIT_MILLIS)
public void asyncUpdateListenerCalled() {
final AtomicInteger _callCount = new AtomicInteger();
final CountDownLatch _fire = new CountDownLatch(1);
Cache<Integer, Integer> c = target.cache(new CacheRule.Specialization<Integer, Integer>() {
@Override
public void extend(final Cache2kBuilder<Integer, Integer> b) {
b.addAsyncListener(new CacheEntryUpdatedListener<Integer, Integer>() {
@Override
public void onEntryUpdated(final Cache<Integer, Integer> cache, final CacheEntry<Integer, Integer> currentEntry, final CacheEntry<Integer, Integer> entryWithNewData) {
try {
_fire.await();
} catch (InterruptedException ignore) {
}
_callCount.incrementAndGet();
}
});
}
});
c.put(1, 2);
assertEquals(0, _callCount.get());
c.put(1, 2);
assertEquals(0, _callCount.get());
_fire.countDown();
ConcurrencyHelper.await(new Condition() {
@Override
public boolean check() throws Exception {
return _callCount.get() == 1;
}
});
}
use of org.cache2k.event.CacheEntryUpdatedListener in project cache2k by cache2k.
the class InternalCache2kBuilder method buildAsIs.
/**
* Build without applying external configuration. Needed for JCache.
*/
@SuppressWarnings({ "unchecked", "SuspiciousToArrayCall" })
public Cache<K, V> buildAsIs() {
if (config.getValueType() == null) {
config.setValueType(Object.class);
}
if (config.getKeyType() == null) {
config.setKeyType(Object.class);
}
if (config.getName() == null) {
config.setName(deriveNameFromStackTrace());
}
checkConfiguration();
Class<?> _implClass = HeapCache.TUNABLE.defaultImplementation;
InternalCache<K, V> _cache = constructImplementationAndFillParameters(_implClass);
InternalClock _timeReference = (InternalClock) _cache.createCustomization(config.getClock());
if (_timeReference == null) {
_timeReference = ClockDefaultImpl.INSTANCE;
}
HeapCache bc = (HeapCache) _cache;
bc.setCacheManager(manager);
if (config.hasCacheClosedListeners()) {
bc.setCacheClosedListeners(config.getCacheClosedListeners());
}
configureViaSettersDirect(bc);
bc.setClock(_timeReference);
boolean _wrap = false;
if (config.hasListeners()) {
_wrap = true;
}
if (config.hasAsyncListeners()) {
_wrap = true;
}
if (config.getWriter() != null) {
_wrap = true;
}
WiredCache<K, V> wc = null;
if (_wrap) {
wc = new WiredCache<K, V>();
wc.heapCache = bc;
_cache = wc;
}
String _name = manager.newCache(_cache, bc.getName());
bc.setName(_name);
if (_wrap) {
wc.loader = bc.loader;
if (config.getWriter() != null) {
wc.writer = (CacheWriter<K, V>) bc.createCustomization(config.getWriter());
}
List<CacheEntryCreatedListener<K, V>> _syncCreatedListeners = new ArrayList<CacheEntryCreatedListener<K, V>>();
List<CacheEntryUpdatedListener<K, V>> _syncUpdatedListeners = new ArrayList<CacheEntryUpdatedListener<K, V>>();
List<CacheEntryRemovedListener<K, V>> _syncRemovedListeners = new ArrayList<CacheEntryRemovedListener<K, V>>();
List<CacheEntryExpiredListener<K, V>> _syncExpiredListeners = new ArrayList<CacheEntryExpiredListener<K, V>>();
List<CacheEntryExpiredListener<K, V>> _expiredListeners = new ArrayList<CacheEntryExpiredListener<K, V>>();
if (config.hasListeners()) {
for (CustomizationSupplier<CacheEntryOperationListener<K, V>> f : config.getListeners()) {
CacheEntryOperationListener<K, V> el = (CacheEntryOperationListener<K, V>) bc.createCustomization(f);
if (el instanceof CacheEntryCreatedListener) {
_syncCreatedListeners.add((CacheEntryCreatedListener) el);
}
if (el instanceof CacheEntryUpdatedListener) {
_syncUpdatedListeners.add((CacheEntryUpdatedListener) el);
}
if (el instanceof CacheEntryRemovedListener) {
_syncRemovedListeners.add((CacheEntryRemovedListener) el);
}
if (el instanceof CacheEntryExpiredListener) {
_expiredListeners.add((CacheEntryExpiredListener) el);
}
}
}
if (config.hasAsyncListeners() || !_expiredListeners.isEmpty()) {
Executor _executor = DEFAULT_ASYNC_EXECUTOR;
if (config.getAsyncListenerExecutor() != null) {
_executor = _cache.createCustomization(config.getAsyncListenerExecutor());
}
AsyncDispatcher<K> _asyncDispatcher = new AsyncDispatcher<K>(wc, _executor);
List<CacheEntryCreatedListener<K, V>> cll = new ArrayList<CacheEntryCreatedListener<K, V>>();
List<CacheEntryUpdatedListener<K, V>> ull = new ArrayList<CacheEntryUpdatedListener<K, V>>();
List<CacheEntryRemovedListener<K, V>> rll = new ArrayList<CacheEntryRemovedListener<K, V>>();
List<CacheEntryExpiredListener<K, V>> ell = new ArrayList<CacheEntryExpiredListener<K, V>>();
for (CustomizationSupplier<CacheEntryOperationListener<K, V>> f : config.getAsyncListeners()) {
CacheEntryOperationListener<K, V> el = (CacheEntryOperationListener<K, V>) bc.createCustomization(f);
if (el instanceof CacheEntryCreatedListener) {
cll.add((CacheEntryCreatedListener) el);
}
if (el instanceof CacheEntryUpdatedListener) {
ull.add((CacheEntryUpdatedListener) el);
}
if (el instanceof CacheEntryRemovedListener) {
rll.add((CacheEntryRemovedListener) el);
}
if (el instanceof CacheEntryExpiredListener) {
ell.add((CacheEntryExpiredListener) el);
}
}
for (CacheEntryCreatedListener l : cll) {
_syncCreatedListeners.add(new AsyncCreatedListener<K, V>(_asyncDispatcher, l));
}
for (CacheEntryUpdatedListener l : ull) {
_syncUpdatedListeners.add(new AsyncUpdatedListener<K, V>(_asyncDispatcher, l));
}
for (CacheEntryRemovedListener l : rll) {
_syncRemovedListeners.add(new AsyncRemovedListener<K, V>(_asyncDispatcher, l));
}
for (CacheEntryExpiredListener l : ell) {
_syncExpiredListeners.add(new AsyncExpiredListener<K, V>(_asyncDispatcher, l));
}
for (CacheEntryExpiredListener l : _expiredListeners) {
_syncExpiredListeners.add(new AsyncExpiredListener<K, V>(_asyncDispatcher, l));
}
}
if (!_syncCreatedListeners.isEmpty()) {
wc.syncEntryCreatedListeners = _syncCreatedListeners.toArray(new CacheEntryCreatedListener[_syncCreatedListeners.size()]);
}
if (!_syncUpdatedListeners.isEmpty()) {
wc.syncEntryUpdatedListeners = _syncUpdatedListeners.toArray(new CacheEntryUpdatedListener[_syncUpdatedListeners.size()]);
}
if (!_syncRemovedListeners.isEmpty()) {
wc.syncEntryRemovedListeners = _syncRemovedListeners.toArray(new CacheEntryRemovedListener[_syncRemovedListeners.size()]);
}
if (!_syncExpiredListeners.isEmpty()) {
wc.syncEntryExpiredListeners = _syncExpiredListeners.toArray(new CacheEntryExpiredListener[_syncExpiredListeners.size()]);
}
bc.eviction = constructEviction(bc, wc, config);
TimingHandler rh = TimingHandler.of(_timeReference, config);
bc.setTiming(rh);
wc.init();
} else {
TimingHandler rh = TimingHandler.of(_timeReference, config);
bc.setTiming(rh);
bc.eviction = constructEviction(bc, HeapCacheListener.NO_OPERATION, config);
bc.init();
}
manager.sendCreatedEvent(_cache);
return _cache;
}
use of org.cache2k.event.CacheEntryUpdatedListener in project cache2k by cache2k.
the class EntryAction method callListeners.
public void callListeners() {
if (!mightHaveListeners()) {
mutationReleaseLockAndStartTimer();
return;
}
CacheEntry<K, V> _currentEntry = heapCache.returnEntry(entry);
if (expiredImmediately) {
if (storageDataValid || heapDataValid) {
if (entryExpiredListeners() != null) {
for (CacheEntryExpiredListener l : entryExpiredListeners()) {
try {
l.onEntryExpired(userCache, _currentEntry);
} catch (Throwable t) {
exceptionToPropagate = new ListenerException(t);
}
}
}
}
} else if (remove) {
if (storageDataValid || heapDataValid) {
if (entryRemovedListeners() != null) {
for (CacheEntryRemovedListener l : entryRemovedListeners()) {
try {
l.onEntryRemoved(userCache, _currentEntry);
} catch (Throwable t) {
exceptionToPropagate = new ListenerException(t);
}
}
}
}
} else {
if (storageDataValid || heapDataValid) {
if (entryUpdatedListeners() != null) {
CacheEntry<K, V> _previousEntry = heapCache.returnCacheEntry(entry.getKey(), oldValueOrException, previousModificationTime);
for (CacheEntryUpdatedListener l : entryUpdatedListeners()) {
try {
l.onEntryUpdated(userCache, _previousEntry, _currentEntry);
} catch (Throwable t) {
exceptionToPropagate = new ListenerException(t);
}
}
}
} else {
if (entryCreatedListeners() != null) {
for (CacheEntryCreatedListener l : entryCreatedListeners()) {
try {
l.onEntryCreated(userCache, _currentEntry);
} catch (Throwable t) {
exceptionToPropagate = new ListenerException(t);
}
}
}
}
}
mutationReleaseLockAndStartTimer();
}
use of org.cache2k.event.CacheEntryUpdatedListener in project cache2k by cache2k.
the class ListenerTest method asyncUpdateListenerException.
@Test
public void asyncUpdateListenerException() {
String _logName = getClass().getName() + ".asyncUpdateListenerException";
final Log.SuppressionCounter _suppressionCounter = new Log.SuppressionCounter();
Log.registerSuppression("org.cache2k.Cache/default:" + _logName, _suppressionCounter);
Cache<Integer, Integer> c = Cache2kBuilder.of(Integer.class, Integer.class).name(_logName).eternal(true).addAsyncListener(new CacheEntryUpdatedListener<Integer, Integer>() {
@Override
public void onEntryUpdated(final Cache<Integer, Integer> cache, final CacheEntry<Integer, Integer> currentEntry, final CacheEntry<Integer, Integer> entryWithNewData) {
throw new RuntimeException("ouch");
}
}).build();
c.put(1, 2);
c.put(1, 2);
ConcurrencyHelper.await(new Condition() {
@Override
public boolean check() throws Exception {
return _suppressionCounter.getWarnCount() == 1;
}
});
c.close();
}
Aggregations