Search in sources :

Example 1 with StateChunk

use of org.infinispan.statetransfer.StateChunk in project infinispan by infinispan.

the class ScatteredStateProviderImpl method invalidateChunks.

private void invalidateChunks(Collection<StateChunk> stateChunks, Set<Address> otherMembers, AtomicInteger outboundInvalidations, CompletableFuture<Void> invalidationFuture, CacheTopology cacheTopology) {
    int numEntries = stateChunks.stream().mapToInt(chunk -> chunk.getCacheEntries().size()).sum();
    if (numEntries == 0) {
        log.tracef("Nothing to invalidate");
        return;
    }
    Object[] keys = new Object[numEntries];
    int[] topologyIds = new int[numEntries];
    long[] versions = new long[numEntries];
    int i = 0;
    for (StateChunk chunk : stateChunks) {
        for (InternalCacheEntry entry : chunk.getCacheEntries()) {
            // we have replicated the non-versioned entries but we won't invalidate them elsewhere
            if (entry.getMetadata() != null && entry.getMetadata().version() != null) {
                keys[i] = entry.getKey();
                SimpleClusteredVersion version = (SimpleClusteredVersion) entry.getMetadata().version();
                topologyIds[i] = version.getTopologyId();
                versions[i] = version.getVersion();
                ++i;
            }
        }
    }
    if (log.isTraceEnabled()) {
        log.tracef("Invalidating %d entries from segments %s", numEntries, stateChunks.stream().map(StateChunk::getSegmentId).collect(Collectors.toList()));
    }
    outboundInvalidations.incrementAndGet();
    rpcManager.invokeCommand(otherMembers, commandsFactory.buildInvalidateVersionsCommand(cacheTopology.getTopologyId(), keys, topologyIds, versions, true), MapResponseCollector.ignoreLeavers(otherMembers.size()), rpcManager.getSyncRpcOptions()).whenComplete((r, t) -> {
        try {
            if (t != null) {
                log.failedInvalidatingRemoteCache(t);
            }
        } finally {
            if (outboundInvalidations.decrementAndGet() == 0) {
                invalidationFuture.complete(null);
            }
        }
    });
}
Also used : InternalCacheEntry(org.infinispan.container.entries.InternalCacheEntry) IntSets(org.infinispan.commons.util.IntSets) LogFactory(org.infinispan.util.logging.LogFactory) RemoteMetadata(org.infinispan.container.entries.RemoteMetadata) CompletableFuture(java.util.concurrent.CompletableFuture) StateProviderImpl(org.infinispan.statetransfer.StateProviderImpl) MapResponseCollector(org.infinispan.remoting.transport.impl.MapResponseCollector) HashSet(java.util.HashSet) StateChunk(org.infinispan.statetransfer.StateChunk) Configurations(org.infinispan.configuration.cache.Configurations) CompletableFutures(org.infinispan.util.concurrent.CompletableFutures) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Log(org.infinispan.util.logging.Log) MarshallableEntry(org.infinispan.persistence.spi.MarshallableEntry) Address(org.infinispan.remoting.transport.Address) Flowable(io.reactivex.rxjava3.core.Flowable) Iterator(java.util.Iterator) Collection(java.util.Collection) Publisher(org.reactivestreams.Publisher) ScatteredStateProvider(org.infinispan.scattered.ScatteredStateProvider) Set(java.util.Set) CacheTopology(org.infinispan.topology.CacheTopology) SimpleClusteredVersion(org.infinispan.container.versioning.SimpleClusteredVersion) Collectors(java.util.stream.Collectors) Inject(org.infinispan.factories.annotations.Inject) IntSet(org.infinispan.commons.util.IntSet) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) OutboundTransferTask(org.infinispan.statetransfer.OutboundTransferTask) ScatteredVersionManager(org.infinispan.scattered.ScatteredVersionManager) SimpleClusteredVersion(org.infinispan.container.versioning.SimpleClusteredVersion) InternalCacheEntry(org.infinispan.container.entries.InternalCacheEntry) StateChunk(org.infinispan.statetransfer.StateChunk)

Example 2 with StateChunk

use of org.infinispan.statetransfer.StateChunk 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

AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Address (org.infinispan.remoting.transport.Address)2 StateChunk (org.infinispan.statetransfer.StateChunk)2 Flowable (io.reactivex.rxjava3.core.Flowable)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Set (java.util.Set)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 CompletionStage (java.util.concurrent.CompletionStage)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Collectors (java.util.stream.Collectors)1 ReplicableCommand (org.infinispan.commands.ReplicableCommand)1 StateResponseCommand (org.infinispan.commands.statetransfer.StateResponseCommand)1 StateTransferGetTransactionsCommand (org.infinispan.commands.statetransfer.StateTransferGetTransactionsCommand)1 StateTransferStartCommand (org.infinispan.commands.statetransfer.StateTransferStartCommand)1 IntSet (org.infinispan.commons.util.IntSet)1 IntSets (org.infinispan.commons.util.IntSets)1