Search in sources :

Example 1 with PerCacheInboundInvocationHandler

use of org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler in project infinispan by infinispan.

the class ConditionalOperationPrimaryOwnerFailTest method testEntryNotWrapped.

public void testEntryNotWrapped() throws Throwable {
    assertClusterSize("Wrong cluster size!", 3);
    final Object key = new MagicKey(cache(0), cache(1));
    final Cache<Object, Object> futureBackupOwnerCache = cache(2);
    cache(0).put(key, INITIAL_VALUE);
    final PerCacheInboundInvocationHandler spyHandler = spyInvocationHandler(futureBackupOwnerCache);
    final EntryFactory spyEntryFactory = spyEntryFactory(futureBackupOwnerCache);
    // it blocks the StateResponseCommand.class
    final CountDownLatch latch1 = new CountDownLatch(1);
    final CountDownLatch latch2 = new CountDownLatch(1);
    doAnswer(invocation -> {
        CacheRpcCommand command = (CacheRpcCommand) invocation.getArguments()[0];
        if (command instanceof StateResponseCommand) {
            log.debugf("Blocking command %s", command);
            latch2.countDown();
            latch1.await();
        }
        return invocation.callRealMethod();
    }).when(spyHandler).handle(any(CacheRpcCommand.class), any(Reply.class), any(DeliverOrder.class));
    doAnswer(invocation -> {
        InvocationContext context = (InvocationContext) invocation.getArguments()[0];
        log.debugf("wrapEntryForWriting invoked with %s", context);
        CompletionStage<Void> stage = (CompletionStage<Void>) invocation.callRealMethod();
        CompletionStages.join(stage);
        assertNull(context.lookupEntry(key), "Entry should not be wrapped!");
        return stage;
    }).when(spyEntryFactory).wrapEntryForWriting(any(InvocationContext.class), any(), anyInt(), anyBoolean(), anyBoolean(), any());
    Future<?> killMemberResult = fork(() -> killMember(1));
    // await until the key is received from state transfer (the command is blocked now...)
    latch2.await(30, TimeUnit.SECONDS);
    futureBackupOwnerCache.put(key, FINAL_VALUE);
    latch1.countDown();
    killMemberResult.get(30, TimeUnit.SECONDS);
}
Also used : EntryFactory(org.infinispan.container.impl.EntryFactory) PerCacheInboundInvocationHandler(org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler) DeliverOrder(org.infinispan.remoting.inboundhandler.DeliverOrder) CountDownLatch(java.util.concurrent.CountDownLatch) CacheRpcCommand(org.infinispan.commands.remote.CacheRpcCommand) StateResponseCommand(org.infinispan.commands.statetransfer.StateResponseCommand) Reply(org.infinispan.remoting.inboundhandler.Reply) InvocationContext(org.infinispan.context.InvocationContext) MagicKey(org.infinispan.distribution.MagicKey) CompletionStage(java.util.concurrent.CompletionStage)

Example 2 with PerCacheInboundInvocationHandler

use of org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler in project infinispan by infinispan.

the class PrepareProcessedAfterOriginatorCrashTest method testBelatedTransactionDoesntLeak.

public void testBelatedTransactionDoesntLeak() throws Throwable {
    CountDownLatch prepareReceived = new CountDownLatch(1);
    CountDownLatch prepareBlocked = new CountDownLatch(1);
    CountDownLatch prepareExecuted = new CountDownLatch(1);
    Cache receiver = cache(1);
    PerCacheInboundInvocationHandler originalInvocationHandler = TestingUtil.extractComponent(receiver, PerCacheInboundInvocationHandler.class);
    PerCacheInboundInvocationHandler blockingInvocationHandler = new AbstractDelegatingHandler(originalInvocationHandler) {

        @Override
        public void handle(CacheRpcCommand command, Reply reply, DeliverOrder order) {
            if (!(command instanceof PrepareCommand)) {
                delegate.handle(command, reply, order);
                return;
            }
            try {
                prepareReceived.countDown();
                prepareBlocked.await(10, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                throw new IllegalLifecycleStateException(e);
            }
            log.trace("Processing belated prepare");
            delegate.handle(command, returnValue -> {
                prepareExecuted.countDown();
                reply.reply(returnValue);
            }, order);
        }
    };
    TestingUtil.replaceComponent(receiver, PerCacheInboundInvocationHandler.class, blockingInvocationHandler, true);
    TestingUtil.extractComponentRegistry(receiver).cacheComponents();
    final Object key = getKeyForCache(1);
    fork(() -> {
        try {
            cache(0).put(key, "v");
        } catch (Throwable e) {
        // possible as the node is being killed
        }
    });
    prepareReceived.await(10, TimeUnit.SECONDS);
    killMember(0);
    // give TransactionTable.cleanupStaleTransactions some time to run
    Thread.sleep(5000);
    prepareBlocked.countDown();
    prepareExecuted.await(10, TimeUnit.SECONDS);
    log.trace("Finished waiting for belated prepare to complete");
    final TransactionTable transactionTable = TestingUtil.getTransactionTable(receiver);
    assertEquals(0, transactionTable.getRemoteTxCount());
    assertEquals(0, transactionTable.getLocalTxCount());
    assertFalse(receiver.getAdvancedCache().getLockManager().isLocked(key));
}
Also used : PerCacheInboundInvocationHandler(org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler) IllegalLifecycleStateException(org.infinispan.commons.IllegalLifecycleStateException) DeliverOrder(org.infinispan.remoting.inboundhandler.DeliverOrder) TransactionTable(org.infinispan.transaction.impl.TransactionTable) PrepareCommand(org.infinispan.commands.tx.PrepareCommand) CountDownLatch(java.util.concurrent.CountDownLatch) AbstractDelegatingHandler(org.infinispan.remoting.inboundhandler.AbstractDelegatingHandler) CacheRpcCommand(org.infinispan.commands.remote.CacheRpcCommand) Reply(org.infinispan.remoting.inboundhandler.Reply) Cache(org.infinispan.Cache)

Example 3 with PerCacheInboundInvocationHandler

use of org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler in project infinispan by infinispan.

the class PushTransferTest method testNodeJoin.

public void testNodeJoin() throws Exception {
    List<MagicKey> keys = init();
    EmbeddedCacheManager cm4 = addClusterEnabledCacheManager(TestDataSCI.INSTANCE, null, TRANSPORT_FLAGS);
    cm4.defineConfiguration(CACHE_NAME, defaultConfig.build());
    int startTopologyId = c1.getAdvancedCache().getDistributionManager().getCacheTopology().getTopologyId();
    BlockingLocalTopologyManager bltm = BlockingLocalTopologyManager.replaceTopologyManager(cm4, CACHE_NAME);
    CountDownLatch statePushedLatch = new CountDownLatch(1);
    CountDownLatch stateAppliedLatch = new CountDownLatch(1);
    TestingUtil.addCacheStartingHook(cm4, (name, cr) -> {
        PerCacheInboundInvocationHandler originalHandler = cr.getComponent(PerCacheInboundInvocationHandler.class);
        AbstractDelegatingHandler newHandler = new AbstractDelegatingHandler(originalHandler) {

            @Override
            public void handle(CacheRpcCommand command, Reply reply, DeliverOrder order) {
                // StateResponseCommand is topology-aware, so handle() just queues it on the remote executor
                if (command instanceof StateResponseCommand) {
                    log.tracef("State received on %s", cm4.getAddress());
                    statePushedLatch.countDown();
                }
                originalHandler.handle(command, response -> {
                    log.tracef("State applied on %s", cm4.getAddress());
                    stateAppliedLatch.countDown();
                    reply.reply(response);
                }, order);
            }
        };
        BasicComponentRegistry bcr = cr.getComponent(BasicComponentRegistry.class);
        bcr.replaceComponent(PerCacheInboundInvocationHandler.class.getName(), newHandler, false);
        cr.rewire();
        cr.cacheComponents();
    });
    Future<Cache> c4Future = fork(() -> cm4.getCache(CACHE_NAME));
    // Any StateResponseCommand should be delayed until node 4 has the TRANSITORY topology
    assertTrue(statePushedLatch.await(10, TimeUnit.SECONDS));
    assertFalse(stateAppliedLatch.await(100, TimeUnit.MILLISECONDS));
    // Finish the rebalance, unblocking the StateResponseCommand(s)
    bltm.confirmTopologyUpdate(CacheTopology.Phase.TRANSITORY);
    assertEquals(0, stateAppliedLatch.getCount());
    bltm.confirmTopologyUpdate(CacheTopology.Phase.NO_REBALANCE);
    Cache c4 = c4Future.get(30, TimeUnit.SECONDS);
    TestingUtil.blockUntilViewsReceived(30000, false, c1, c2, c3, c4);
    TestingUtil.waitForNoRebalance(c1, c2, c3, c4);
    for (MagicKey key : keys) {
        int copies = Stream.of(c1, c2, c3, c4).mapToInt(c -> c.getAdvancedCache().getDataContainer().containsKey(key) ? 1 : 0).sum();
        assertEquals("Key " + key + " has incorrect number of copies", 2, copies);
    }
}
Also used : MagicKey(org.infinispan.distribution.MagicKey) TestDataSCI(org.infinispan.test.TestDataSCI) BlockingLocalTopologyManager(org.infinispan.util.BlockingLocalTopologyManager) StateResponseCommand(org.infinispan.commands.statetransfer.StateResponseCommand) Reply(org.infinispan.remoting.inboundhandler.Reply) AssertJUnit.assertFalse(org.testng.AssertJUnit.assertFalse) Test(org.testng.annotations.Test) CacheTopology(org.infinispan.topology.CacheTopology) Cache(org.infinispan.Cache) BiasAcquisition(org.infinispan.configuration.cache.BiasAcquisition) AssertJUnit.assertTrue(org.testng.AssertJUnit.assertTrue) AbstractDelegatingHandler(org.infinispan.remoting.inboundhandler.AbstractDelegatingHandler) TimeUnit(java.util.concurrent.TimeUnit) CountDownLatch(java.util.concurrent.CountDownLatch) BasicComponentRegistry(org.infinispan.factories.impl.BasicComponentRegistry) List(java.util.List) Future(java.util.concurrent.Future) CacheRpcCommand(org.infinispan.commands.remote.CacheRpcCommand) Stream(java.util.stream.Stream) EmbeddedCacheManager(org.infinispan.manager.EmbeddedCacheManager) PerCacheInboundInvocationHandler(org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler) TestingUtil(org.infinispan.test.TestingUtil) DeliverOrder(org.infinispan.remoting.inboundhandler.DeliverOrder) AssertJUnit.assertEquals(org.testng.AssertJUnit.assertEquals) PerCacheInboundInvocationHandler(org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler) BlockingLocalTopologyManager(org.infinispan.util.BlockingLocalTopologyManager) DeliverOrder(org.infinispan.remoting.inboundhandler.DeliverOrder) EmbeddedCacheManager(org.infinispan.manager.EmbeddedCacheManager) CountDownLatch(java.util.concurrent.CountDownLatch) BasicComponentRegistry(org.infinispan.factories.impl.BasicComponentRegistry) AbstractDelegatingHandler(org.infinispan.remoting.inboundhandler.AbstractDelegatingHandler) CacheRpcCommand(org.infinispan.commands.remote.CacheRpcCommand) Reply(org.infinispan.remoting.inboundhandler.Reply) StateResponseCommand(org.infinispan.commands.statetransfer.StateResponseCommand) MagicKey(org.infinispan.distribution.MagicKey) Cache(org.infinispan.Cache)

Example 4 with PerCacheInboundInvocationHandler

use of org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler in project infinispan by infinispan.

the class TestingUtil method wrapInboundInvocationHandler.

public static <T extends PerCacheInboundInvocationHandler> T wrapInboundInvocationHandler(Cache<?, ?> cache, Function<PerCacheInboundInvocationHandler, T> ctor) {
    PerCacheInboundInvocationHandler current = extractComponent(cache, PerCacheInboundInvocationHandler.class);
    T wrap = ctor.apply(current);
    replaceComponent(cache, PerCacheInboundInvocationHandler.class, wrap, true);
    return wrap;
}
Also used : PerCacheInboundInvocationHandler(org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler)

Example 5 with PerCacheInboundInvocationHandler

use of org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler in project infinispan by infinispan.

the class StateResponseOrderingTest method testSimulatedOldStateResponse.

public void testSimulatedOldStateResponse() throws Throwable {
    // Initial owners for both segments are cache 1, 2, and 3
    // Start a rebalance, with cache 0 becoming an owner of both CH segments
    // Block the first StateTransferStartCommand on cache 0
    // While state transfer is blocked, simulate an old state response command on cache 0
    // Check that the old command is ignored and state transfer completes successfully
    StateSequencer sequencer = new StateSequencer();
    sequencer.logicalThread("st", "st:block_state_request", "st:simulate_old_response", "st:resume_state_request");
    cache(1).put("k1", "v1");
    cache(2).put("k2", "v2");
    cache(3).put("k3", "v3");
    DistributionManager dm0 = advancedCache(0).getDistributionManager();
    final int initialTopologyId = dm0.getCacheTopology().getTopologyId();
    assertEquals(Arrays.asList(address(1), address(2), address(3)), dm0.getCacheTopology().getDistribution("k1").readOwners());
    assertNull(dm0.getCacheTopology().getPendingCH());
    // Block when cache 0 sends the first state request to cache 1
    CommandMatcher segmentRequestMatcher = command -> command instanceof StateTransferStartCommand && ((StateTransferStartCommand) command).getTopologyId() == initialTopologyId + 1;
    advanceOnOutboundRpc(sequencer, cache(0), segmentRequestMatcher).before("st:block_state_request", "st:resume_state_request");
    // Cache 0 will become an owner and will request state from cache 1
    consistentHashFactory.setOwnerIndexes(new int[][] { { 0, 1, 2 }, { 0, 1, 2 } });
    consistentHashFactory.triggerRebalance(cache(0));
    sequencer.enter("st:simulate_old_response");
    assertNotNull(dm0.getCacheTopology().getPendingCH());
    assertEquals(Arrays.asList(address(0), address(1), address(2)), dm0.getCacheTopology().getPendingCH().locateOwnersForSegment(0));
    assertEquals(Arrays.asList(address(1), address(2), address(3), address(0)), dm0.getCacheTopology().getDistribution("k1").writeOwners());
    // Cache 0 didn't manage to request any segments yet, but it has registered all the inbound transfer tasks.
    // We'll pretend it got a StateResponseCommand with an older topology id.
    PerCacheInboundInvocationHandler handler = TestingUtil.extractComponent(cache(0), PerCacheInboundInvocationHandler.class);
    StateChunk stateChunk0 = new StateChunk(0, Arrays.asList(new ImmortalCacheEntry("k0", "v0")), true);
    StateChunk stateChunk1 = new StateChunk(1, Arrays.asList(new ImmortalCacheEntry("k0", "v0")), true);
    String cacheName = manager(0).getCacheManagerConfiguration().defaultCacheName().get();
    StateResponseCommand stateResponseCommand = new StateResponseCommand(ByteString.fromString(cacheName), initialTopologyId, Arrays.asList(stateChunk0, stateChunk1), true, false);
    // Call with preserveOrder = true to force the execution in the same thread
    stateResponseCommand.setOrigin(address(3));
    handler.handle(stateResponseCommand, Reply.NO_OP, DeliverOrder.PER_SENDER);
    sequencer.exit("st:simulate_old_response");
    waitForNoRebalance(cache(0), cache(1), cache(2), cache(3));
    // Check that state wasn't lost
    assertTrue(dm0.getCacheTopology().isReadOwner("k1"));
    assertTrue(dm0.getCacheTopology().isReadOwner("k2"));
    assertTrue(dm0.getCacheTopology().isReadOwner("k3"));
    assertEquals("v1", cache(0).get("k1"));
    assertEquals("v2", cache(0).get("k2"));
    assertEquals("v3", cache(0).get("k3"));
    // Check that the old state response was ignored
    assertNull(cache(0).get("k0"));
}
Also used : CommandMatcher(org.infinispan.test.concurrent.CommandMatcher) ControlledConsistentHashFactory(org.infinispan.util.ControlledConsistentHashFactory) Arrays(java.util.Arrays) ConfigurationBuilder(org.infinispan.configuration.cache.ConfigurationBuilder) StateSequencerUtil.advanceOnInboundRpc(org.infinispan.test.concurrent.StateSequencerUtil.advanceOnInboundRpc) Reply(org.infinispan.remoting.inboundhandler.Reply) StateTransferStartCommand(org.infinispan.commands.statetransfer.StateTransferStartCommand) Test(org.testng.annotations.Test) AtomicReference(java.util.concurrent.atomic.AtomicReference) CommandMatcher(org.infinispan.test.concurrent.CommandMatcher) ImmortalCacheEntry(org.infinispan.container.entries.ImmortalCacheEntry) StateChunk(org.infinispan.statetransfer.StateChunk) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AssertJUnit.assertNull(org.testng.AssertJUnit.assertNull) TestingUtil(org.infinispan.test.TestingUtil) StateSequencer(org.infinispan.test.concurrent.StateSequencer) Address(org.infinispan.remoting.transport.Address) ByteString(org.infinispan.util.ByteString) MagicKey(org.infinispan.distribution.MagicKey) TestDataSCI(org.infinispan.test.TestDataSCI) TestingUtil.waitForNoRebalance(org.infinispan.test.TestingUtil.waitForNoRebalance) ReplicableCommand(org.infinispan.commands.ReplicableCommand) CleanupAfterMethod(org.infinispan.test.fwk.CleanupAfterMethod) MultipleCacheManagersTest(org.infinispan.test.MultipleCacheManagersTest) StateResponseCommand(org.infinispan.commands.statetransfer.StateResponseCommand) Assert.assertNotNull(org.testng.Assert.assertNotNull) StateTransferManager(org.infinispan.statetransfer.StateTransferManager) StateSequencerUtil.matchCommand(org.infinispan.test.concurrent.StateSequencerUtil.matchCommand) CacheMode(org.infinispan.configuration.cache.CacheMode) PerCacheInboundInvocationHandler(org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler) StateTransferGetTransactionsCommand(org.infinispan.commands.statetransfer.StateTransferGetTransactionsCommand) TestCacheManagerFactory(org.infinispan.test.fwk.TestCacheManagerFactory) Assert.assertTrue(org.testng.Assert.assertTrue) DeliverOrder(org.infinispan.remoting.inboundhandler.DeliverOrder) AssertJUnit.assertEquals(org.testng.AssertJUnit.assertEquals) StateSequencerUtil.advanceOnOutboundRpc(org.infinispan.test.concurrent.StateSequencerUtil.advanceOnOutboundRpc) DistributionManager(org.infinispan.distribution.DistributionManager) StateSequencer(org.infinispan.test.concurrent.StateSequencer) PerCacheInboundInvocationHandler(org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler) ImmortalCacheEntry(org.infinispan.container.entries.ImmortalCacheEntry) StateTransferStartCommand(org.infinispan.commands.statetransfer.StateTransferStartCommand) StateResponseCommand(org.infinispan.commands.statetransfer.StateResponseCommand) ByteString(org.infinispan.util.ByteString) DistributionManager(org.infinispan.distribution.DistributionManager) StateChunk(org.infinispan.statetransfer.StateChunk)

Aggregations

PerCacheInboundInvocationHandler (org.infinispan.remoting.inboundhandler.PerCacheInboundInvocationHandler)6 DeliverOrder (org.infinispan.remoting.inboundhandler.DeliverOrder)5 CountDownLatch (java.util.concurrent.CountDownLatch)3 Cache (org.infinispan.Cache)3 CacheRpcCommand (org.infinispan.commands.remote.CacheRpcCommand)3 StateResponseCommand (org.infinispan.commands.statetransfer.StateResponseCommand)3 Reply (org.infinispan.remoting.inboundhandler.Reply)3 TestingUtil (org.infinispan.test.TestingUtil)3 Test (org.testng.annotations.Test)3 Arrays (java.util.Arrays)2 List (java.util.List)2 CompletionStage (java.util.concurrent.CompletionStage)2 Future (java.util.concurrent.Future)2 TimeUnit (java.util.concurrent.TimeUnit)2 StateTransferGetTransactionsCommand (org.infinispan.commands.statetransfer.StateTransferGetTransactionsCommand)2 StateTransferStartCommand (org.infinispan.commands.statetransfer.StateTransferStartCommand)2 CacheMode (org.infinispan.configuration.cache.CacheMode)2 ConfigurationBuilder (org.infinispan.configuration.cache.ConfigurationBuilder)2 ImmortalCacheEntry (org.infinispan.container.entries.ImmortalCacheEntry)2 DistributionManager (org.infinispan.distribution.DistributionManager)2