use of org.infinispan.interceptors.BaseCustomAsyncInterceptor in project infinispan by infinispan.
the class LockingTest method injectBlockingCommandInterceptor.
private CheckPoint injectBlockingCommandInterceptor(String cacheName) {
final CheckPoint checkPoint = new CheckPoint();
TestingUtil.extractInterceptorChain(cache(cacheName)).addInterceptorBefore(new BaseCustomAsyncInterceptor() {
private final AtomicBoolean first = new AtomicBoolean(false);
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) {
if (first.compareAndSet(false, true)) {
checkPoint.trigger("before-block");
return asyncInvokeNext(ctx, command, checkPoint.future("block", 30, TimeUnit.SECONDS, testExecutor()));
}
return invokeNext(ctx, command);
}
}, CallInterceptor.class);
return checkPoint;
}
use of org.infinispan.interceptors.BaseCustomAsyncInterceptor in project infinispan by infinispan.
the class InfinispanNodeFailureTest method killedNodeDoesNotBreakReplaceCommand.
public void killedNodeDoesNotBreakReplaceCommand() throws Exception {
defineConfigurationOnAllManagers(TEST_CACHE, new ConfigurationBuilder().read(manager(0).getDefaultCacheConfiguration()));
waitForClusterToForm(TEST_CACHE);
waitForNoRebalance(caches(TEST_CACHE));
final Object replaceKey = new MagicKey("X", cache(0, TEST_CACHE));
final Object putKey = new MagicKey("Z", cache(1, TEST_CACHE));
cache(0, TEST_CACHE).put(replaceKey, INITIAL_VALUE);
// prepare third node to notify us when put command is in progress so we can kill the node
final CountDownLatch beforeKill = new CountDownLatch(1);
final CountDownLatch afterKill = new CountDownLatch(1);
advancedCache(1, TEST_CACHE).getAsyncInterceptorChain().addInterceptor(new BaseCustomAsyncInterceptor() {
@Override
public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand command) throws Throwable {
return invokeNextAndFinally(ctx, command, (rCtx, rCommand, rv, t) -> {
LockControlCommand cmd = (LockControlCommand) rCommand;
if (putKey.equals(cmd.getSingleKey())) {
// notify main thread it can start killing third node
beforeKill.countDown();
// wait for completion and proceed
afterKill.await(10, TimeUnit.SECONDS);
}
});
}
}, 1);
// execute replace command in separate thread so we can do something else meanwhile
Future<Boolean> firstResult = fork(() -> {
try {
tm(0, TEST_CACHE).begin();
// this should replace and lock REPLACE_KEY so other transactions can't pass this barrier
boolean result = cache(0, TEST_CACHE).replace(replaceKey, INITIAL_VALUE, REPLACING_VALUE);
// issue put command so it is retried while node-c is being killed
cache(0, TEST_CACHE).put(putKey, "some-value");
// apply new view
viewLatch.countDown();
tm(0, TEST_CACHE).commit();
return result;
} catch (Throwable t) {
return null;
}
});
// wait third node to complete replace command and kill it
assertTrue(beforeKill.await(10, TimeUnit.SECONDS));
// kill node-c, do not wait rehash, it is important to continue with put-retry before new view is received
killMember(2, TEST_CACHE, false);
afterKill.countDown();
tm(1, TEST_CACHE).begin();
// this replace should never succeed because first node has already replaced and locked value
// but during put command replace lock is lost, so we can successfully replace the same value again, which is a bug
boolean secondResult = cache(1, TEST_CACHE).replace(replaceKey, INITIAL_VALUE, REPLACING_VALUE);
tm(1, TEST_CACHE).commit();
// check that first node did not fail
assertEquals(Boolean.TRUE, firstResult.get());
assertEquals(REPLACING_VALUE, cache(0, TEST_CACHE).get(replaceKey));
assertEquals(REPLACING_VALUE, cache(1, TEST_CACHE).get(replaceKey));
// check that second node state is inconsistent, second result should be FALSE in read committed pessimistic cache
// uncomment when this bug is fixed
assertEquals(false, secondResult);
}
use of org.infinispan.interceptors.BaseCustomAsyncInterceptor in project infinispan by infinispan.
the class CustomLoaderNonNullWithExpirationTest method testExpireAfterWrapping.
public void testExpireAfterWrapping() {
// Every time a get is invoked it increases time by 2 seconds - causing entry to expire
cache.getAdvancedCache().getAsyncInterceptorChain().addInterceptorAfter(new BaseCustomAsyncInterceptor() {
@Override
public Object visitGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable {
timeService.advance(TimeUnit.SECONDS.toMillis(2));
return super.visitGetKeyValueCommand(ctx, command);
}
}, EntryWrappingInterceptor.class);
String key = "some-key";
Object value = cache.get(key);
assertEquals(SimpleLoader.VALUE, value);
value = cache.get(key);
assertEquals(SimpleLoader.VALUE, value);
}
use of org.infinispan.interceptors.BaseCustomAsyncInterceptor in project infinispan by infinispan.
the class CustomLoaderNonNullWithExpirationTest method testConcurrentReadExpiration.
public void testConcurrentReadExpiration() throws InterruptedException, TimeoutException, BrokenBarrierException, ExecutionException {
AtomicBoolean blockFirst = new AtomicBoolean(true);
CyclicBarrier barrier = new CyclicBarrier(2);
String key = "some-key";
// We block the first get attempt, which will have no entry in data container in EntryWrappingInterceptor
// But after we unblock it, the data container will have an expired entry
cache.getAdvancedCache().getAsyncInterceptorChain().addInterceptorAfter(new BaseCustomAsyncInterceptor() {
@Override
public Object visitGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable {
if (blockFirst.getAndSet(false)) {
assertEquals(NullCacheEntry.getInstance(), ctx.lookupEntry(key));
barrier.await(10, TimeUnit.SECONDS);
barrier.await(10, TimeUnit.SECONDS);
}
return super.visitGetKeyValueCommand(ctx, command);
}
}, EntryWrappingInterceptor.class);
// This method will block above
Future<Void> future = fork(() -> assertEquals(SimpleLoader.VALUE, cache.get(key)));
// Make sure forked thread is blocked after EntryWrappingInterceptor, but before CacheLoaderInterceptor
barrier.await(10, TimeUnit.SECONDS);
// Now we read the key which should load the value
Object value = cache.get(key);
assertEquals(SimpleLoader.VALUE, value);
// This will cause it to expire
timeService.advance(TimeUnit.SECONDS.toMillis(2));
// Finally let the fork complete - should be fine
barrier.await(10, TimeUnit.SECONDS);
future.get(10, TimeUnit.SECONDS);
}
use of org.infinispan.interceptors.BaseCustomAsyncInterceptor in project infinispan by infinispan.
the class NonTxStateTransferInvalidationTest method testInvalidationDuringStateTransfer.
public void testInvalidationDuringStateTransfer() throws Exception {
EmbeddedCacheManager node1 = manager(0);
Cache<String, Object> node1Cache = node1.getCache();
EmbeddedCacheManager node2 = manager(1);
Cache<String, Object> node2Cache = node2.getCache();
CountDownLatch latch = new CountDownLatch(1);
node2Cache.getAdvancedCache().getAsyncInterceptorChain().addInterceptor(new BaseCustomAsyncInterceptor() {
@Override
public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand command) throws Throwable {
latch.await(10, TimeUnit.SECONDS);
return super.visitInvalidateCommand(ctx, command);
}
}, 0);
String key = "key";
Future<?> future = fork(() -> {
node1Cache.putForExternalRead(key, new Object());
node1Cache.remove(key);
});
EmbeddedCacheManager node3 = addClusterEnabledCacheManager(dccc);
Cache<Object, Object> node3Cache = node3.getCache();
TestingUtil.waitForNoRebalance(caches());
log.info("Node 3 started");
latch.countDown();
future.get(30, TimeUnit.SECONDS);
assertNull(node1Cache.get(key));
assertNull(node2Cache.get(key));
assertNull(node3Cache.get(key));
}
Aggregations