Search in sources :

Example 1 with BlockTcpDiscoverySpi

use of org.apache.ignite.spi.discovery.tcp.BlockTcpDiscoverySpi in project ignite by apache.

the class TxPartitionCounterStateConsistencyTest method testPartitionConsistencyDuringRebalanceAndConcurrentUpdates_LateAffinitySwitch.

/**
 * Tests tx load concurrently with PME for switching late affinity.
 * <p>
 * Scenario: two keys tx mapped locally on late affinity topology and when mapped and prepared remotely on ideal
 * topology, first key is mapped to non-moving partition, second is mapped on moving partition.
 * <p>
 * Success: key over moving partition is prepared on new owner (choosed after late affinity switch),
 * otherwise it's possible txs are prepared on different primaries after late affinity switch.
 */
@Test
public void testPartitionConsistencyDuringRebalanceAndConcurrentUpdates_LateAffinitySwitch() throws Exception {
    backups = 1;
    customDiscoSpi = new BlockTcpDiscoverySpi().setIpFinder(IP_FINDER);
    Field rndAddrsField = U.findField(BlockTcpDiscoverySpi.class, "skipAddrsRandomization");
    assertNotNull(rndAddrsField);
    rndAddrsField.set(customDiscoSpi, true);
    // Start coordinator with custom discovery SPI.
    IgniteEx crd = startGrid(0);
    IgniteEx g1 = startGrid(1);
    startGrid(2);
    crd.cluster().baselineAutoAdjustEnabled(false);
    crd.cluster().active(true);
    // Same name pattern as in test configuration.
    String consistentId = "node" + getTestIgniteInstanceName(3);
    List<Integer> g1Keys = primaryKeys(g1.cache(DEFAULT_CACHE_NAME), 10);
    List<Integer> movingFromG1 = movingKeysAfterJoin(g1, DEFAULT_CACHE_NAME, 10, null, consistentId);
    // Retain only stable keys;
    g1Keys.removeAll(movingFromG1);
    // The key will move from grid0 to grid3.
    Integer key = movingKeysAfterJoin(crd, DEFAULT_CACHE_NAME, 1, null, consistentId).get(0);
    IgniteEx g3 = startGrid(3);
    assertEquals(consistentId, g3.localNode().consistentId());
    resetBaselineTopology();
    awaitPartitionMapExchange();
    assertTrue(crd.affinity(DEFAULT_CACHE_NAME).isPrimary(g1.localNode(), g1Keys.get(0)));
    stopGrid(3);
    Ignite client = startClientGrid(CLIENT_GRID_NAME);
    IgniteCache<Object, Object> cache = client.cache(DEFAULT_CACHE_NAME);
    IgniteCache<Object, Object> cache2 = client.getOrCreateCache(cacheConfiguration(DEFAULT_CACHE_NAME + "2"));
    // Put one key per partition.
    for (int k = 0; k < partitions(); k++) {
        cache.put(k, 0);
        cache2.put(k, 0);
    }
    CountDownLatch resumeDiscoSndLatch = new CountDownLatch(1);
    BlockTcpDiscoverySpi crdDiscoSpi = (BlockTcpDiscoverySpi) grid(0).configuration().getDiscoverySpi();
    CyclicBarrier sync = new CyclicBarrier(2);
    crdDiscoSpi.setClosure((node, msg) -> {
        if (msg instanceof CacheAffinityChangeMessage) {
            U.awaitQuiet(sync);
            U.awaitQuiet(resumeDiscoSndLatch);
        }
        return null;
    });
    // Locks mapped wait.
    IgniteInternalFuture fut = GridTestUtils.runAsync(() -> {
        try {
            startGrid(SERVER_NODES);
            awaitPartitionMapExchange();
        } catch (Exception e) {
            fail(X.getFullStackTrace(e));
        }
    });
    sync.await();
    TestRecordingCommunicationSpi clientSpi = TestRecordingCommunicationSpi.spi(client);
    clientSpi.blockMessages((node, msg) -> msg instanceof GridNearLockRequest);
    IgniteInternalFuture txFut = GridTestUtils.runAsync(() -> {
        try (Transaction tx = client.transactions().txStart()) {
            Map<Integer, Integer> map = new LinkedHashMap<>();
            // clientFirst=true in lockAll mapped to stable part.
            map.put(g1Keys.get(0), g1Keys.get(0));
            // clientFirst=false in lockAll mapped to moving part.
            map.put(key, key);
            cache.putAll(map);
            cache2.putAll(new LinkedHashMap<>(map));
            // Will start preparing in the middle of PME.
            tx.commit();
        }
    });
    IgniteInternalFuture lockFut = GridTestUtils.runAsync(() -> {
        try {
            // Wait for first lock request sent on local (late) topology.
            clientSpi.waitForBlocked();
            // Continue late switch PME.
            resumeDiscoSndLatch.countDown();
            crdDiscoSpi.setClosure(null);
            // Wait late affinity switch.
            awaitPartitionMapExchange();
            // Continue tx mapping and preparing.
            clientSpi.stopBlock();
        } catch (InterruptedException e) {
            fail(X.getFullStackTrace(e));
        }
    });
    fut.get();
    txFut.get();
    lockFut.get();
    assertPartitionsSame(idleVerify(crd, DEFAULT_CACHE_NAME));
    // TX must be prepared over new owner.
    PartitionUpdateCounter cntr = counter(key, grid(3).name());
    assertNotNull(cntr);
    assertEquals(cntr.toString(), 2, cntr.reserved());
    PartitionUpdateCounter cntr2 = counter(key, DEFAULT_CACHE_NAME + "2", grid(3).name());
    assertNotNull(cntr2);
    assertEquals(cntr2.toString(), 2, cntr2.reserved());
}
Also used : GridNearLockRequest(org.apache.ignite.internal.processors.cache.distributed.near.GridNearLockRequest) PartitionUpdateCounter(org.apache.ignite.internal.processors.cache.PartitionUpdateCounter) CountDownLatch(java.util.concurrent.CountDownLatch) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteFutureTimeoutCheckedException(org.apache.ignite.internal.IgniteFutureTimeoutCheckedException) ClusterTopologyException(org.apache.ignite.cluster.ClusterTopologyException) CacheInvalidStateException(org.apache.ignite.internal.processors.cache.CacheInvalidStateException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) TransactionRollbackException(org.apache.ignite.transactions.TransactionRollbackException) CyclicBarrier(java.util.concurrent.CyclicBarrier) LinkedHashMap(java.util.LinkedHashMap) Field(java.lang.reflect.Field) CacheAffinityChangeMessage(org.apache.ignite.internal.processors.cache.CacheAffinityChangeMessage) TestRecordingCommunicationSpi(org.apache.ignite.internal.TestRecordingCommunicationSpi) Transaction(org.apache.ignite.transactions.Transaction) BlockTcpDiscoverySpi(org.apache.ignite.spi.discovery.tcp.BlockTcpDiscoverySpi) IgniteEx(org.apache.ignite.internal.IgniteEx) Ignite(org.apache.ignite.Ignite) Test(org.junit.Test)

Example 2 with BlockTcpDiscoverySpi

use of org.apache.ignite.spi.discovery.tcp.BlockTcpDiscoverySpi in project ignite by apache.

the class BinaryMetadataConcurrentUpdateWithIndexesTest method testMissingSchemaUpdate.

/**
 */
@Test
public void testMissingSchemaUpdate() throws Exception {
    // Start order is important.
    Ignite node0 = startGrid("node0");
    Ignite node1 = startGrid("node1");
    IgniteEx client0 = startClientGrid("client0");
    CacheObjectBinaryProcessorImpl.TestBinaryContext clientCtx = (CacheObjectBinaryProcessorImpl.TestBinaryContext) ((CacheObjectBinaryProcessorImpl) client0.context().cacheObjects()).binaryContext();
    clientCtx.addListener(new CacheObjectBinaryProcessorImpl.TestBinaryContext.TestBinaryContextListener() {

        @Override
        public void onAfterMetadataRequest(int typeId, BinaryType type) {
            if (syncMeta) {
                try {
                    initMetaReq.countDown();
                    initMetaReq.await();
                } catch (Exception e) {
                    throw new BinaryObjectException(e);
                }
            }
        }

        @Override
        public void onBeforeMetadataUpdate(int typeId, BinaryMetadata metadata) {
            // Delay one of updates until schema is locally updated on propose message.
            if (delayMetadataUpdateThreadLoc.get() != null)
                await(localMetaUpdatedLatch, 5000);
        }
    });
    Ignite node2 = startGrid("node2");
    Ignite node3 = startGrid("node3");
    startGrid("node4");
    node0.cluster().active(true);
    awaitPartitionMapExchange();
    syncMeta = true;
    CountDownLatch clientProposeMsgBlockedLatch = new CountDownLatch(1);
    AtomicBoolean clientWait = new AtomicBoolean();
    final Object clientMux = new Object();
    AtomicBoolean srvWait = new AtomicBoolean();
    final Object srvMux = new Object();
    ((BlockTcpDiscoverySpi) node1.configuration().getDiscoverySpi()).setClosure((snd, msg) -> {
        if (msg instanceof MetadataUpdateProposedMessage) {
            if (Thread.currentThread().getName().contains("client")) {
                log.info("Block custom message to client0: [locNode=" + snd + ", msg=" + msg + ']');
                clientProposeMsgBlockedLatch.countDown();
                // Message to client
                synchronized (clientMux) {
                    while (!clientWait.get()) try {
                        clientMux.wait();
                    } catch (InterruptedException e) {
                        fail();
                    }
                }
            }
        }
        return null;
    });
    ((BlockTcpDiscoverySpi) node2.configuration().getDiscoverySpi()).setClosure((snd, msg) -> {
        if (msg instanceof MetadataUpdateProposedMessage) {
            MetadataUpdateProposedMessage msg0 = (MetadataUpdateProposedMessage) msg;
            int pendingVer = U.field(msg0, "pendingVer");
            // Should not block propose messages until they reach coordinator.
            if (pendingVer == 0)
                return null;
            log.info("Block custom message to next server: [locNode=" + snd + ", msg=" + msg + ']');
            // Message to client
            synchronized (srvMux) {
                while (!srvWait.get()) try {
                    srvMux.wait();
                } catch (InterruptedException e) {
                    fail();
                }
            }
        }
        return null;
    });
    Integer key = primaryKey(node3.cache(DEFAULT_CACHE_NAME));
    IgniteInternalFuture fut0 = runAsync(() -> {
        try (Transaction tx = client0.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
            client0.cache(DEFAULT_CACHE_NAME).put(key, build(client0, "val", 0));
            tx.commit();
        } catch (Throwable t) {
            log.error("err", t);
        }
    });
    // Implements test logic.
    IgniteInternalFuture fut1 = runAsync(() -> {
        // Wait for initial metadata received. It should be initial version: pending=0, accepted=0
        await(initMetaReq, 5000);
        // Wait for blocking proposal message to client node.
        await(clientProposeMsgBlockedLatch, 5000);
        // Unblock proposal message to client.
        clientWait.set(true);
        synchronized (clientMux) {
            clientMux.notify();
        }
        // Give some time to apply update.
        doSleep(3000);
        // Unblock second metadata update.
        localMetaUpdatedLatch.countDown();
        // Give some time for tx to complete (success or fail). fut2 will throw an error if tx has failed on commit.
        doSleep(3000);
        // Unblock metadata message and allow for correct version acceptance.
        srvWait.set(true);
        synchronized (srvMux) {
            srvMux.notify();
        }
    });
    IgniteInternalFuture fut2 = runAsync(() -> {
        delayMetadataUpdateThreadLoc.set(true);
        try (Transaction tx = client0.transactions().txStart(PESSIMISTIC, REPEATABLE_READ, 0, 1)) {
            client0.cache(DEFAULT_CACHE_NAME).put(key, build(client0, "val", 0));
            tx.commit();
        }
    });
    fut0.get();
    fut1.get();
    fut2.get();
}
Also used : BinaryType(org.apache.ignite.binary.BinaryType) CacheObjectBinaryProcessorImpl(org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl) CountDownLatch(java.util.concurrent.CountDownLatch) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) BinaryMetadata(org.apache.ignite.internal.binary.BinaryMetadata) BinaryObjectException(org.apache.ignite.binary.BinaryObjectException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Transaction(org.apache.ignite.transactions.Transaction) MetadataUpdateProposedMessage(org.apache.ignite.internal.processors.cache.binary.MetadataUpdateProposedMessage) BlockTcpDiscoverySpi(org.apache.ignite.spi.discovery.tcp.BlockTcpDiscoverySpi) IgniteEx(org.apache.ignite.internal.IgniteEx) Ignite(org.apache.ignite.Ignite) BinaryObject(org.apache.ignite.binary.BinaryObject) BinaryObjectException(org.apache.ignite.binary.BinaryObjectException) GridCommonAbstractTest(org.apache.ignite.testframework.junits.common.GridCommonAbstractTest) Test(org.junit.Test)

Example 3 with BlockTcpDiscoverySpi

use of org.apache.ignite.spi.discovery.tcp.BlockTcpDiscoverySpi in project ignite by apache.

the class BinaryMetadataConcurrentUpdateWithIndexesTest method getConfiguration.

/**
 * {@inheritDoc}
 */
@Override
protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
    IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
    cfg.setIncludeEventTypes(EventType.EVTS_DISCOVERY);
    BlockTcpDiscoverySpi spi = new BlockTcpDiscoverySpi();
    Field rndAddrsField = U.findField(BlockTcpDiscoverySpi.class, "skipAddrsRandomization");
    assertNotNull(rndAddrsField);
    rndAddrsField.set(spi, true);
    cfg.setDiscoverySpi(spi.setIpFinder(sharedStaticIpFinder));
    QueryEntity qryEntity = new QueryEntity("java.lang.Integer", "Value");
    LinkedHashMap<String, String> fields = new LinkedHashMap<>();
    Collection<QueryIndex> indexes = new ArrayList<>(FIELDS);
    for (int i = 0; i < FIELDS; i++) {
        String name = "s" + i;
        fields.put(name, "java.lang.String");
        indexes.add(new QueryIndex(name, QueryIndexType.SORTED));
    }
    qryEntity.setFields(fields);
    qryEntity.setIndexes(indexes);
    cfg.setDataStorageConfiguration(new DataStorageConfiguration().setDefaultDataRegionConfiguration(new DataRegionConfiguration().setMaxSize(50 * MB)));
    cfg.setCacheConfiguration(new CacheConfiguration(DEFAULT_CACHE_NAME).setBackups(0).setQueryEntities(Collections.singleton(qryEntity)).setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL).setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC).setCacheMode(CacheMode.PARTITIONED));
    return cfg;
}
Also used : ArrayList(java.util.ArrayList) QueryEntity(org.apache.ignite.cache.QueryEntity) LinkedHashMap(java.util.LinkedHashMap) DataStorageConfiguration(org.apache.ignite.configuration.DataStorageConfiguration) Field(java.lang.reflect.Field) DataRegionConfiguration(org.apache.ignite.configuration.DataRegionConfiguration) IgniteConfiguration(org.apache.ignite.configuration.IgniteConfiguration) BlockTcpDiscoverySpi(org.apache.ignite.spi.discovery.tcp.BlockTcpDiscoverySpi) QueryIndex(org.apache.ignite.cache.QueryIndex) CacheConfiguration(org.apache.ignite.configuration.CacheConfiguration)

Aggregations

BlockTcpDiscoverySpi (org.apache.ignite.spi.discovery.tcp.BlockTcpDiscoverySpi)3 Field (java.lang.reflect.Field)2 LinkedHashMap (java.util.LinkedHashMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 Ignite (org.apache.ignite.Ignite)2 IgniteEx (org.apache.ignite.internal.IgniteEx)2 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)2 Transaction (org.apache.ignite.transactions.Transaction)2 Test (org.junit.Test)2 ArrayList (java.util.ArrayList)1 CyclicBarrier (java.util.concurrent.CyclicBarrier)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 BinaryObject (org.apache.ignite.binary.BinaryObject)1 BinaryObjectException (org.apache.ignite.binary.BinaryObjectException)1 BinaryType (org.apache.ignite.binary.BinaryType)1 QueryEntity (org.apache.ignite.cache.QueryEntity)1 QueryIndex (org.apache.ignite.cache.QueryIndex)1 ClusterTopologyException (org.apache.ignite.cluster.ClusterTopologyException)1 CacheConfiguration (org.apache.ignite.configuration.CacheConfiguration)1