use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.PartitionsExchangeAware in project ignite by apache.
the class PendingExchangeTest method createClusterWithPendingExchnageDuringRebalance.
/**
* @param clo Closure triggering exchange.
* @throws Exception If failed.
*/
private void createClusterWithPendingExchnageDuringRebalance(PendingExchangeTrigger clo) throws Exception {
IgniteEx ignite0 = startGrids(3);
try (IgniteDataStreamer streamer = ignite0.dataStreamer(DEFAULT_CACHE_NAME)) {
for (int i = 0; i < 1000; i++) streamer.addData(i, i);
}
awaitPartitionMapExchange();
GridCachePartitionExchangeManager exchangeManager1 = ignite(1).context().cache().context().exchange();
CountDownLatch exchangeLatch = new CountDownLatch(1);
AffinityTopologyVersion readyTop = exchangeManager1.readyAffinityVersion();
exchangeManager1.registerExchangeAwareComponent(new PartitionsExchangeAware() {
@Override
public void onInitAfterTopologyLock(GridDhtPartitionsExchangeFuture fut) {
U.awaitQuiet(exchangeLatch);
}
});
IgniteInternalFuture startNodeFut = GridTestUtils.runAsync(() -> stopGrid(2));
assertTrue(GridTestUtils.waitForCondition(() -> exchangeManager1.lastTopologyFuture().initialVersion().after(readyTop), 10_000));
IgniteInternalFuture exchangeTrigger = clo.trigger(ignite0, exchangeManager1);
assertTrue(GridTestUtils.waitForCondition(exchangeManager1::hasPendingServerExchange, 10_000));
exchangeLatch.countDown();
startNodeFut.get(10_000);
exchangeTrigger.get(10_000);
awaitPartitionMapExchange();
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.PartitionsExchangeAware in project ignite by apache.
the class IgniteExchangeLatchManagerDiscoHistoryTest method testProperException.
/**
* @throws Exception If failed.
*/
@Test
@WithSystemProperty(key = IGNITE_DISCOVERY_HISTORY_SIZE, value = DISCO_HISTORY_SIZE)
public void testProperException() throws Exception {
final IgniteEx crd = startGrid(0);
final CountDownLatch exchangeLatch = new CountDownLatch(1);
final CountDownLatch startSrvsLatch = new CountDownLatch(1);
final AtomicReference<Exception> err = new AtomicReference<>();
// Lifecycle bean that is used to register PartitionsExchangeAware listener.
lifecycleBean = new LifecycleBean() {
/**
* Ignite instance.
*/
@IgniteInstanceResource
IgniteEx ignite;
/**
* {@inheritDoc}
*/
@Override
public void onLifecycleEvent(LifecycleEventType evt) throws IgniteException {
if (evt == LifecycleEventType.BEFORE_NODE_START) {
// The goal is registering PartitionsExchangeAware listener before the discovery manager is started.
ignite.context().internalSubscriptionProcessor().registerDistributedMetastorageListener(new DistributedMetastorageLifecycleListener() {
@Override
public void onReadyForRead(ReadableDistributedMetaStorage metastorage) {
ignite.context().cache().context().exchange().registerExchangeAwareComponent(new PartitionsExchangeAware() {
/**
* {@inheritDoc}
*/
@Override
public void onInitBeforeTopologyLock(GridDhtPartitionsExchangeFuture fut) {
try {
// Let's start nodes.
startSrvsLatch.countDown();
// Blocks the initial exchange and waits for other nodes.
exchangeLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (Exception e) {
err.compareAndSet(null, e);
}
}
});
}
});
}
}
};
// Start server node with short topology history.
victim = true;
GridTestUtils.runAsync(() -> startGrid(1));
// Waits for the initial exchange.
startSrvsLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
victim = false;
lifecycleBean = null;
List<IgniteInternalFuture> srvFuts = new ArrayList<>(TOPOLOGY_HISTORY_SIZE);
try {
// Major topology version that is corresponding to the start of the node with short topology history.
final long topVer = 2;
// Starting server nodes to exhaust the topology history.
for (int i = 2; i < 3 * TOPOLOGY_HISTORY_SIZE && !disco.isEmptyTopologyHistory(topVer); ++i) {
final int currNodeIdx = i;
final int joinedNodesCnt = disco.totalJoinedNodes();
srvFuts.add(GridTestUtils.runAsync(() -> startGrid(currNodeIdx)));
assertTrue("Failed to wait for a new server node [joinedNodesCnt=" + joinedNodesCnt + "]", GridTestUtils.waitForCondition(() -> disco.totalJoinedNodes() >= (joinedNodesCnt + 1), DEFAULT_TIMEOUT));
}
assertTrue("Disco cache history is not empty for the topology [majorTopVer=" + topVer + ']', disco.isEmptyTopologyHistory(topVer));
// Let's continue the ongoing exchange.
exchangeLatch.countDown();
boolean failureHnd = GridTestUtils.waitForCondition(() -> cpFailureCtx.get() != null, DEFAULT_TIMEOUT);
assertNull("Unexpected exception (probably, the topology history still exists [err=" + err + ']', err.get());
assertTrue("Failure handler was not triggered.", failureHnd);
// Check that IgniteException was thrown instead of NullPointerException.
assertTrue("IgniteException must be thrown.", X.hasCause(cpFailureCtx.get().error(), IgniteException.class));
// Check that message contains a hint to fix the issue.
GridTestUtils.assertContains(log, cpFailureCtx.get().error().getMessage(), "Consider increasing IGNITE_DISCOVERY_HISTORY_SIZE property. Current value is " + DISCO_HISTORY_SIZE);
} finally {
IgnitionEx.stop(getTestIgniteInstanceName(1), true, ShutdownPolicy.IMMEDIATE, true);
srvFuts.forEach(f -> {
try {
f.get(DEFAULT_TIMEOUT);
} catch (IgniteCheckedException e) {
err.compareAndSet(null, e);
}
});
}
assertNull("Unexpected exception [err=" + err.get() + ']', err.get());
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.PartitionsExchangeAware in project ignite by apache.
the class StartImplicitlyTxOnStopCacheTest method test.
/**
* @throws Exception If failed.
*/
@Test
public void test() throws Exception {
IgniteEx ignite0 = startGrid(0);
IgniteEx client = startClientGrid("client");
IgniteCache<Object, Object> cache = client.cache(DEFAULT_CACHE_NAME);
for (int i = 0; i < 100; i++) cache.put(i, i);
TestRecordingCommunicationSpi commSpiClient = TestRecordingCommunicationSpi.spi(client);
commSpiClient.blockMessages(GridNearTxPrepareRequest.class, getTestIgniteInstanceName(0));
CyclicBarrier exchnageStartedBarrier = new CyclicBarrier(2, commSpiClient::stopBlock);
ignite0.context().cache().context().exchange().registerExchangeAwareComponent(new PartitionsExchangeAware() {
@Override
public void onInitBeforeTopologyLock(GridDhtPartitionsExchangeFuture fut) {
try {
exchnageStartedBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
log.error("Exchange delay was interrupted.", e);
}
}
});
IgniteInternalFuture runTxFut = GridTestUtils.runAsync(() -> cache.put(100, 100));
IgniteInternalFuture destroyCacheFut = GridTestUtils.runAsync(() -> client.destroyCache(DEFAULT_CACHE_NAME));
exchnageStartedBarrier.await();
assertTrue(GridTestUtils.waitForCondition(destroyCacheFut::isDone, 10_000));
assertTrue(GridTestUtils.waitForCondition(runTxFut::isDone, 10_000));
assertNull(client.cache(DEFAULT_CACHE_NAME));
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.PartitionsExchangeAware in project ignite by apache.
the class PartitionsExchangeAwareTest method testPartitionsExchangeAware.
/**
* Checks that updates are impossible during PME exactly from the moment topologies are locked
* and until exchange future is completed.
*
* @throws Exception if failed.
*/
@Test
public void testPartitionsExchangeAware() throws Exception {
startGrids(2);
awaitPartitionMapExchange();
IgniteEx ig0 = grid(0);
IgniteEx ig1 = grid(1);
IgniteCache<Integer, Integer> atomicCache = ig0.cache(ATOMIC_CACHE_NAME);
IgniteCache<Integer, Integer> txCache = ig1.cache(TX_CACHE_NAME);
PartitionsExchangeAware exchangeAware = new PartitionsExchangeAware() {
/**
* {@inheritDoc}
*/
@Override
public void onInitBeforeTopologyLock(GridDhtPartitionsExchangeFuture fut) {
try {
initBeforeLockReachedLatch.countDown();
initBeforeLockWaitLatch.await();
} catch (InterruptedException e) {
throw new IgniteInterruptedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public void onInitAfterTopologyLock(GridDhtPartitionsExchangeFuture fut) {
try {
initAfterLockReachedLatch.countDown();
initAfterLockWaitLatch.await();
} catch (InterruptedException e) {
throw new IgniteInterruptedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public void onDoneBeforeTopologyUnlock(GridDhtPartitionsExchangeFuture fut) {
try {
onDoneBeforeUnlockReachedLatch.countDown();
onDoneBeforeUnlockWaitLatch.await();
} catch (InterruptedException e) {
throw new IgniteInterruptedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public void onDoneAfterTopologyUnlock(GridDhtPartitionsExchangeFuture fut) {
try {
onDoneAfterUnlockReachedLatch.countDown();
onDoneAfterUnlockWaitLatch.await();
} catch (InterruptedException e) {
throw new IgniteInterruptedException(e);
}
}
};
ig0.context().cache().context().exchange().registerExchangeAwareComponent(exchangeAware);
ig1.context().cache().context().exchange().registerExchangeAwareComponent(exchangeAware);
GridTestUtils.runAsync(() -> startGrid(2));
assertTrue(initBeforeLockReachedLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS));
assertUpdateIsPossible(atomicCache, txCache, true);
initBeforeLockWaitLatch.countDown();
assertTrue(initAfterLockReachedLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS));
assertUpdateIsPossible(atomicCache, txCache, false);
initAfterLockWaitLatch.countDown();
assertTrue(onDoneBeforeUnlockReachedLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS));
assertUpdateIsPossible(atomicCache, txCache, false);
onDoneBeforeUnlockWaitLatch.countDown();
assertTrue(onDoneAfterUnlockReachedLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS));
assertUpdateIsPossible(atomicCache, txCache, true);
onDoneAfterUnlockWaitLatch.countDown();
System.out.println("^^^^success");
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.PartitionsExchangeAware in project ignite by apache.
the class DelayedOwningDuringExchangeTest method testDelayedRenting.
/**
* @param idx Index.
* @param mode Mode.
*/
private void testDelayedRenting(int idx, int mode) throws Exception {
final int nodes = 2;
IgniteEx crd = startGrids(nodes);
awaitPartitionMapExchange();
IgniteEx testGrid = grid(idx);
CountDownLatch l1 = new CountDownLatch(1);
CountDownLatch l2 = new CountDownLatch(1);
testGrid.context().cache().context().exchange().registerExchangeAwareComponent(new PartitionsExchangeAware() {
@Override
public void onInitAfterTopologyLock(GridDhtPartitionsExchangeFuture fut) {
wait(fut, 0);
}
@Override
public void onDoneBeforeTopologyUnlock(GridDhtPartitionsExchangeFuture fut) {
wait(fut, 1);
}
private void wait(GridDhtPartitionsExchangeFuture fut, int mode0) {
if (fut.initialVersion().equals(new AffinityTopologyVersion(nodes + 2, 0)) && mode == mode0) {
l1.countDown();
try {
assertTrue(U.await(l2, 30_000, TimeUnit.MILLISECONDS));
} catch (IgniteInterruptedCheckedException e) {
fail(X.getFullStackTrace(e));
}
}
}
});
int p0 = evictingPartitionsAfterJoin(testGrid, testGrid.cache(DEFAULT_CACHE_NAME), 1).get(0);
testGrid.cache(DEFAULT_CACHE_NAME).put(p0, 0);
GridDhtPartitionTopology top0 = testGrid.cachex(DEFAULT_CACHE_NAME).context().topology();
GridDhtLocalPartition evictPart = top0.localPartition(p0);
assertTrue(evictPart.reserve());
IgniteEx joined = startGrid(nodes);
GridDhtPartitionTopology top1 = joined.cachex(DEFAULT_CACHE_NAME).context().topology();
assertTrue(GridTestUtils.waitForCondition(() -> top0.nodes(p0, new AffinityTopologyVersion(nodes + 1, 1)).size() == 2, 5_000));
assertTrue(GridTestUtils.waitForCondition(() -> top1.nodes(p0, new AffinityTopologyVersion(nodes + 1, 1)).size() == 2, 5_000));
Collection<ClusterNode> affOwners = testGrid.affinity(DEFAULT_CACHE_NAME).mapPartitionToPrimaryAndBackups(p0);
assertEquals(1, affOwners.size());
IgniteInternalFuture fut = GridTestUtils.runAsync(new Runnable() {
@Override
public void run() {
stopGrid(nodes);
}
});
assertTrue(U.await(l1, 30_000, TimeUnit.MILLISECONDS));
evictPart.release();
doSleep(1000);
l2.countDown();
awaitPartitionMapExchange(true, true, null);
fut.get();
assertEquals(0, testGrid.cache(DEFAULT_CACHE_NAME).get(p0));
}
Aggregations