use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.latch.ExchangeLatchManager in project ignite by apache.
the class IgniteExchangeLatchManagerCoordinatorFailTest method testCoordinatorFailoverAfterServerLatchCompleted.
/**
* @throws Exception if failed.
*/
@Test
public void testCoordinatorFailoverAfterServerLatchCompleted() throws Exception {
Latch[] latches = new Latch[5];
for (int i = 0; i < 5; i++) {
ExchangeLatchManager latchMgr = grid(i).context().cache().context().exchange().latch();
latches[i] = latchMgr.getOrCreate(LATCH_DROP_NAME, latchTopVer);
info("Created latch: " + i);
latches[i].countDown();
}
for (int i = 0; i < 4; i++) {
info("Waiting for latch: " + i);
latches[i].await(10_000, TimeUnit.MILLISECONDS);
}
stopGrid(0);
for (int i = 1; i < 5; i++) {
info("Waiting for latch after stop: " + i);
latches[i].await(10_000, TimeUnit.MILLISECONDS);
}
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.latch.ExchangeLatchManager in project ignite by apache.
the class IgniteExchangeLatchManagerCoordinatorFailTest method doTestCoordinatorFail.
/**
* Test latch coordinator fail with specified scenarios.
*
* @param nodeScenarios Node scenarios.
* @throws Exception If failed.
*/
private void doTestCoordinatorFail(List<IgniteBiClosure<ExchangeLatchManager, CountDownLatch, Boolean>> nodeScenarios) throws Exception {
IgniteEx latchCrd = grid(LATCH_CRD_INDEX);
// Latch to synchronize node states.
CountDownLatch syncLatch = new CountDownLatch(5);
GridCompoundFuture finishAllLatches = new GridCompoundFuture();
AtomicBoolean hasErrors = new AtomicBoolean();
int scenarioIdx = 0;
for (int nodeId = 0; nodeId < 5; nodeId++) {
if (nodeId == LATCH_CRD_INDEX)
continue;
IgniteEx grid = grid(nodeId);
ExchangeLatchManager latchMgr = grid.context().cache().context().exchange().latch();
IgniteBiClosure<ExchangeLatchManager, CountDownLatch, Boolean> scenario = nodeScenarios.get(scenarioIdx);
IgniteInternalFuture<?> fut = GridTestUtils.runMultiThreadedAsync(() -> {
boolean success = scenario.apply(latchMgr, syncLatch);
if (!success)
hasErrors.set(true);
}, 1, "latch-runner-" + nodeId);
finishAllLatches.add(fut);
scenarioIdx++;
}
finishAllLatches.markInitialized();
// Wait while all nodes reaches their states.
while (syncLatch.getCount() != 1) {
U.sleep(10);
if (hasErrors.get())
throw new Exception("All nodes should complete latches without errors");
}
latchCrd.close();
// Resume progress for all nodes.
syncLatch.countDown();
// Wait for distributed latch completion.
finishAllLatches.get(5000);
Assert.assertFalse("All nodes should complete latches without errors", hasErrors.get());
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.latch.ExchangeLatchManager in project ignite by apache.
the class GridCachePartitionExchangeManager method start0.
/**
* {@inheritDoc}
*/
@Override
protected void start0() throws IgniteCheckedException {
super.start0();
exchWorker = new ExchangeWorker();
latchMgr = new ExchangeLatchManager(cctx.kernalContext());
cctx.gridEvents().addDiscoveryEventListener(discoLsnr, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_NODE_FAILED, EVT_DISCOVERY_CUSTOM_EVT);
cctx.io().addCacheHandler(0, GridDhtPartitionsSingleMessage.class, new MessageHandler<GridDhtPartitionsSingleMessage>() {
@Override
public void onMessage(final ClusterNode node, final GridDhtPartitionsSingleMessage msg) {
GridDhtPartitionExchangeId exchangeId = msg.exchangeId();
if (exchangeId != null) {
GridDhtPartitionsExchangeFuture fut = exchangeFuture(exchangeId);
boolean fastReplied = fut.fastReplyOnSingleMessage(node, msg);
if (fastReplied) {
if (log.isInfoEnabled())
log.info("Fast replied to single message " + "[exchId=" + exchangeId + ", nodeId=" + node.id() + "]");
return;
}
} else {
GridDhtPartitionsExchangeFuture cur = lastTopologyFuture();
if (!cur.isDone() && cur.changedAffinity() && !msg.restoreState()) {
cur.listen(new IgniteInClosure<IgniteInternalFuture<AffinityTopologyVersion>>() {
@Override
public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
if (fut.error() == null)
processSinglePartitionUpdate(node, msg);
}
});
return;
}
}
processSinglePartitionUpdate(node, msg);
}
});
cctx.io().addCacheHandler(0, GridDhtPartitionsFullMessage.class, new MessageHandler<GridDhtPartitionsFullMessage>() {
@Override
public void onMessage(ClusterNode node, GridDhtPartitionsFullMessage msg) {
if (msg.exchangeId() == null) {
GridDhtPartitionsExchangeFuture currentExchange = lastTopologyFuture();
if (currentExchange != null && currentExchange.addOrMergeDelayedFullMessage(node, msg)) {
if (log.isInfoEnabled()) {
log.info("Delay process full message without exchange id (there is exchange in progress) " + "[nodeId=" + node.id() + "]");
}
return;
}
}
processFullPartitionUpdate(node, msg);
}
});
cctx.io().addCacheHandler(0, GridDhtPartitionsSingleRequest.class, new MessageHandler<GridDhtPartitionsSingleRequest>() {
@Override
public void onMessage(ClusterNode node, GridDhtPartitionsSingleRequest msg) {
processSinglePartitionRequest(node, msg);
}
});
if (!cctx.kernalContext().clientNode()) {
for (int cnt = 0; cnt < cctx.gridConfig().getRebalanceThreadPoolSize(); cnt++) {
final int idx = cnt;
cctx.io().addOrderedCacheGroupHandler(cctx, rebalanceTopic(cnt), new CI2<UUID, GridCacheGroupIdMessage>() {
@Override
public void apply(final UUID id, final GridCacheGroupIdMessage m) {
if (!enterBusy())
return;
try {
CacheGroupContext grp = cctx.cache().cacheGroup(m.groupId());
if (grp != null) {
if (m instanceof GridDhtPartitionSupplyMessage) {
grp.preloader().handleSupplyMessage(id, (GridDhtPartitionSupplyMessage) m);
return;
} else if (m instanceof GridDhtPartitionDemandMessage) {
grp.preloader().handleDemandMessage(idx, id, (GridDhtPartitionDemandMessage) m);
return;
} else if (m instanceof GridDhtPartitionDemandLegacyMessage) {
grp.preloader().handleDemandMessage(idx, id, new GridDhtPartitionDemandMessage((GridDhtPartitionDemandLegacyMessage) m));
return;
} else
U.error(log, "Unsupported message type: " + m.getClass().getName());
}
U.warn(log, "Cache group with id=" + m.groupId() + " is stopped or absent");
} finally {
leaveBusy();
}
}
});
}
}
MetricRegistry mreg = cctx.kernalContext().metric().registry(PME_METRICS);
mreg.register(PME_DURATION, () -> currentPMEDuration(false), "Current PME duration in milliseconds.");
mreg.register(PME_OPS_BLOCKED_DURATION, () -> currentPMEDuration(true), "Current PME cache operations blocked duration in milliseconds.");
durationHistogram = mreg.findMetric(PME_DURATION_HISTOGRAM);
blockingDurationHistogram = mreg.findMetric(PME_OPS_BLOCKED_DURATION_HISTOGRAM);
MetricRegistry clusterReg = cctx.kernalContext().metric().registry(CLUSTER_METRICS);
rebalanced = clusterReg.booleanMetric(REBALANCED, "True if the cluster has fully achieved rebalanced state. Note that an inactive cluster always has" + " this metric in False regardless of the real partitions state.");
startLatch.countDown();
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.latch.ExchangeLatchManager in project ignite by apache.
the class IgniteExchangeLatchManagerCoordinatorFailTest method waitForLatchesCleanup.
/**
* Waits until latches are cleaned up after exchange.
*/
private void waitForLatchesCleanup() throws IgniteInterruptedCheckedException {
for (int i = 0; i < 5; i++) {
int finalI = i;
assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
@Override
public boolean apply() {
ExchangeLatchManager mgr = grid(finalI).context().cache().context().exchange().latch();
Map serverLatches = U.field(mgr, "serverLatches");
if (!serverLatches.isEmpty())
return false;
Map clientLatches = U.field(mgr, "clientLatches");
if (!clientLatches.isEmpty())
return false;
return true;
}
}, 5_000));
}
}
Aggregations