use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class JobStealingCollisionSpi method onContextInitialized0.
/**
* {@inheritDoc}
*/
@Override
protected void onContextInitialized0(IgniteSpiContext spiCtx) throws IgniteSpiException {
spiCtx.addLocalEventListener(discoLsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent;
DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
UUID evtNodeId = discoEvt.eventNode().id();
switch(discoEvt.type()) {
case EVT_NODE_JOINED:
ClusterNode node = getSpiContext().node(evtNodeId);
if (node != null) {
nodeQueue.offer(node);
sndMsgMap.putIfAbsent(node.id(), new MessageInfo());
rcvMsgMap.putIfAbsent(node.id(), new MessageInfo());
}
break;
case EVT_NODE_LEFT:
case EVT_NODE_FAILED:
Iterator<ClusterNode> iter = nodeQueue.iterator();
while (iter.hasNext()) {
ClusterNode nextNode = iter.next();
if (nextNode.id().equals(evtNodeId))
iter.remove();
}
sndMsgMap.remove(evtNodeId);
rcvMsgMap.remove(evtNodeId);
break;
default:
assert false : "Unexpected event: " + evt;
}
}
}, EVT_NODE_FAILED, EVT_NODE_JOINED, EVT_NODE_LEFT);
Collection<ClusterNode> rmtNodes = spiCtx.remoteNodes();
for (ClusterNode node : rmtNodes) {
UUID id = node.id();
if (spiCtx.node(id) != null) {
sndMsgMap.putIfAbsent(id, new MessageInfo());
rcvMsgMap.putIfAbsent(id, new MessageInfo());
// Check if node has concurrently left.
if (spiCtx.node(id) == null) {
sndMsgMap.remove(id);
rcvMsgMap.remove(id);
}
}
}
nodeQueue.addAll(rmtNodes);
Iterator<ClusterNode> iter = nodeQueue.iterator();
while (iter.hasNext()) {
ClusterNode nextNode = iter.next();
if (spiCtx.node(nextNode.id()) == null)
iter.remove();
}
spiCtx.addMessageListener(msgLsnr = new GridMessageListener() {
@Override
public void onMessage(UUID nodeId, Object msg, byte plc) {
MessageInfo info = rcvMsgMap.get(nodeId);
if (info == null) {
if (log.isDebugEnabled())
log.debug("Ignoring message steal request as discovery event has not yet been received " + "for node: " + nodeId);
return;
}
int stealReqs0;
synchronized (info) {
JobStealingRequest req = (JobStealingRequest) msg;
// Increment total number of steal requests.
// Note that it is critical to increment total
// number of steal requests before resetting message info.
stealReqs0 = stealReqs.addAndGet(req.delta() - info.jobsToSteal());
info.reset(req.delta());
}
if (log.isDebugEnabled())
log.debug("Received steal request [nodeId=" + nodeId + ", msg=" + msg + ", stealReqs=" + stealReqs0 + ']');
CollisionExternalListener tmp = extLsnr;
// Let grid know that collisions should be resolved.
if (tmp != null)
tmp.onExternalCollision();
}
}, JOB_STEALING_COMM_TOPIC);
}
use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class IgniteClientCheckClusterGroupLocalIdAfterReconnect method testClusterGroupLocalIdAfterClientReconnect.
/**
* Test checks that local id in cluster group was change and client
* will be able to send the message to itself after reconnect.
*/
@Test
public void testClusterGroupLocalIdAfterClientReconnect() throws Exception {
Ignite server = startGrid(0);
Ignite client = startClientGrid(1);
UUID clientId = client.cluster().node().id();
ClusterGroup cg1 = client.cluster().forLocal();
assertNotNull("Local client ID is different with local ClusterGroup node id. ", cg1.node(clientId));
// check sending messages is possible while connected
IgniteMessaging messaging = client.message(client.cluster().forLocal());
CountDownLatch topicSignal = new CountDownLatch(2);
messaging.localListen("topic", (IgniteBiPredicate<UUID, Object>) (uuid, n) -> {
topicSignal.countDown();
return true;
});
// countDown latch = 1
messaging.send("topic", new External());
CountDownLatch discSignal = new CountDownLatch(1);
client.events().localListen((IgnitePredicate<DiscoveryEvent>) evt -> {
discSignal.countDown();
return true;
}, EventType.EVT_CLIENT_NODE_DISCONNECTED);
server.close();
assertTrue("client did not disconnect", discSignal.await(LATCH_TIMEOUT, TimeUnit.SECONDS));
startGrid(0);
// wait for client reconnect
IgniteFuture future = client.cluster().clientReconnectFuture();
assertNotNull(future);
// throws if times out
future.get(20_000);
ClusterGroup cg2 = client.cluster().forLocal();
UUID newClientId = client.cluster().localNode().id();
assertNotNull("Local client ID wasn't changed for local ClusterGroup.", cg2.node(newClientId));
awaitPartitionMapExchange();
// check sending messages is possible after reconnecting
// countDown latch = 0
messaging = client.message(client.cluster().forLocal());
messaging.send("topic", new External());
assertTrue("Message wasn't received", topicSignal.await(LATCH_TIMEOUT, TimeUnit.SECONDS));
}
use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class AdaptiveLoadBalancingSpi method onContextInitialized0.
/**
* {@inheritDoc}
*/
@Override
protected void onContextInitialized0(IgniteSpiContext spiCtx) throws IgniteSpiException {
getSpiContext().addLocalEventListener(evtLsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
switch(evt.type()) {
case EVT_TASK_FINISHED:
case EVT_TASK_FAILED:
{
TaskEvent taskEvt = (TaskEvent) evt;
taskTops.remove(taskEvt.taskSessionId());
if (log.isDebugEnabled())
log.debug("Removed task topology from topology cache for session: " + taskEvt.taskSessionId());
break;
}
case EVT_JOB_MAPPED:
{
// We should keep topology and use cache in ComputeTask#map() method to
// avoid O(n*n/2) complexity, after that we can drop caches.
// Here we set mapped property and later cache will be ignored
JobEvent jobEvt = (JobEvent) evt;
IgniteBiTuple<Boolean, WeightedTopology> weightedTop = taskTops.get(jobEvt.taskSessionId());
if (weightedTop != null)
weightedTop.set1(true);
if (log.isDebugEnabled())
log.debug("Job has been mapped. Ignore cache for session: " + jobEvt.taskSessionId());
break;
}
case EVT_NODE_METRICS_UPDATED:
case EVT_NODE_FAILED:
case EVT_NODE_JOINED:
case EVT_NODE_LEFT:
{
DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
rwLock.writeLock().lock();
try {
switch(evt.type()) {
case EVT_NODE_JOINED:
{
nodeJobs.put(discoEvt.eventNode().id(), new AtomicInteger(0));
break;
}
case EVT_NODE_LEFT:
case EVT_NODE_FAILED:
{
nodeJobs.remove(discoEvt.eventNode().id());
break;
}
case EVT_NODE_METRICS_UPDATED:
{
// Reset counter.
nodeJobs.put(discoEvt.eventNode().id(), new AtomicInteger(0));
break;
}
}
} finally {
rwLock.writeLock().unlock();
}
}
}
}
}, EVT_NODE_METRICS_UPDATED, EVT_NODE_FAILED, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_TASK_FINISHED, EVT_TASK_FAILED, EVT_JOB_MAPPED);
// Put all known nodes.
rwLock.writeLock().lock();
try {
for (ClusterNode node : getSpiContext().nodes()) nodeJobs.put(node.id(), new AtomicInteger(0));
} finally {
rwLock.writeLock().unlock();
}
}
use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class RoundRobinGlobalLoadBalancer method onContextInitialized.
/**
* @param ctx Load balancing context.
*/
void onContextInitialized(final IgniteSpiContext ctx) {
this.ctx = ctx;
ctx.addLocalEventListener(lsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent;
UUID nodeId = ((DiscoveryEvent) evt).eventNode().id();
synchronized (mux) {
if (evt.type() == EVT_NODE_JOINED) {
List<UUID> oldNodes = nodeList.getNodes();
if (!oldNodes.contains(nodeId)) {
List<UUID> newNodes = new ArrayList<>(oldNodes.size() + 1);
newNodes.add(nodeId);
for (UUID node : oldNodes) newNodes.add(node);
nodeList = new GridNodeList(0, newNodes);
}
} else if (evt.type() == EVT_CLIENT_NODE_RECONNECTED) {
Collection<ClusterNode> nodes = ((DiscoveryEvent) evt).topologyNodes();
List<UUID> newNodes = new ArrayList<>(nodes.size());
for (ClusterNode node : nodes) newNodes.add(node.id());
nodeList = new GridNodeList(0, newNodes);
} else {
assert evt.type() == EVT_NODE_LEFT || evt.type() == EVT_NODE_FAILED;
List<UUID> oldNodes = nodeList.getNodes();
if (oldNodes.contains(nodeId)) {
List<UUID> newNodes = new ArrayList<>(oldNodes.size() - 1);
for (UUID node : oldNodes) if (!nodeId.equals(node))
newNodes.add(node);
nodeList = new GridNodeList(0, newNodes);
}
}
}
}
}, EVT_NODE_FAILED, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_CLIENT_NODE_RECONNECTED);
synchronized (mux) {
List<UUID> oldNodes = nodeList.getNodes();
Collection<UUID> set = oldNodes == null ? new HashSet<UUID>() : new HashSet<>(oldNodes);
for (ClusterNode node : ctx.nodes()) set.add(node.id());
nodeList = new GridNodeList(0, new ArrayList<>(set));
}
initLatch.countDown();
}
use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.
the class CacheLateAffinityAssignmentTest method calculateAffinity.
/**
* @param topVer Topology version.
* @param filterByRcvd If {@code true} filters caches by 'receivedFrom' property.
* @param cur Optional current affinity.
* @throws Exception If failed.
* @return {@code True} if some primary node changed comparing to given affinity.
*/
private boolean calculateAffinity(long topVer, boolean filterByRcvd, @Nullable Map<String, List<List<ClusterNode>>> cur) throws Exception {
List<Ignite> all = G.allGrids();
IgniteKernal ignite = (IgniteKernal) Collections.min(all, new Comparator<Ignite>() {
@Override
public int compare(Ignite n1, Ignite n2) {
return Long.compare(n1.cluster().localNode().order(), n2.cluster().localNode().order());
}
});
assert !all.isEmpty();
Map<Integer, List<List<ClusterNode>>> assignments = idealAff.get(topVer);
if (assignments == null)
idealAff.put(topVer, assignments = new HashMap<>());
GridKernalContext ctx = ignite.context();
GridCacheSharedContext cctx = ctx.cache().context();
AffinityTopologyVersion topVer0 = new AffinityTopologyVersion(topVer);
cctx.discovery().topologyFuture(topVer).get();
List<GridDhtPartitionsExchangeFuture> futs = cctx.exchange().exchangeFutures();
DiscoveryEvent evt = null;
long stopTime = System.currentTimeMillis() + 10_000;
boolean primaryChanged = false;
do {
for (int i = futs.size() - 1; i >= 0; i--) {
GridDhtPartitionsExchangeFuture fut = futs.get(i);
if (fut.initialVersion().equals(topVer0)) {
evt = fut.firstEvent();
break;
}
}
if (evt == null) {
U.sleep(500);
futs = cctx.exchange().exchangeFutures();
} else
break;
} while (System.currentTimeMillis() < stopTime);
assertNotNull("Failed to find exchange future:", evt);
Collection<ClusterNode> allNodes = ctx.discovery().serverNodes(topVer0);
for (DynamicCacheDescriptor cacheDesc : ctx.cache().cacheDescriptors().values()) {
if (assignments.get(cacheDesc.cacheId()) != null)
continue;
if (filterByRcvd && cacheDesc.receivedFrom() != null && ctx.discovery().node(topVer0, cacheDesc.receivedFrom()) == null)
continue;
AffinityFunction func = cacheDesc.cacheConfiguration().getAffinity();
func = cctx.cache().clone(func);
cctx.kernalContext().resource().injectGeneric(func);
List<ClusterNode> affNodes = new ArrayList<>();
IgnitePredicate<ClusterNode> filter = cacheDesc.cacheConfiguration().getNodeFilter();
for (ClusterNode n : allNodes) {
if (!n.isClient() && (filter == null || filter.apply(n)))
affNodes.add(n);
}
Collections.sort(affNodes, NodeOrderComparator.getInstance());
AffinityFunctionContext affCtx = new GridAffinityFunctionContextImpl(affNodes, previousAssignment(topVer, cacheDesc.cacheId()), evt, topVer0, cacheDesc.cacheConfiguration().getBackups());
List<List<ClusterNode>> assignment = func.assignPartitions(affCtx);
if (cur != null) {
List<List<ClusterNode>> prev = cur.get(cacheDesc.cacheConfiguration().getName());
assertEquals(prev.size(), assignment.size());
if (!primaryChanged) {
for (int p = 0; p < prev.size(); p++) {
List<ClusterNode> nodes0 = prev.get(p);
List<ClusterNode> nodes1 = assignment.get(p);
if (!nodes0.isEmpty() && !nodes1.isEmpty()) {
ClusterNode p0 = nodes0.get(0);
ClusterNode p1 = nodes1.get(0);
if (allNodes.contains(p0) && !p0.equals(p1)) {
primaryChanged = true;
log.info("Primary changed [cache=" + cacheDesc.cacheConfiguration().getName() + ", part=" + p + ", prev=" + F.nodeIds(nodes0) + ", new=" + F.nodeIds(nodes1) + ']');
break;
}
}
}
}
}
assignments.put(cacheDesc.cacheId(), assignment);
}
return primaryChanged;
}
Aggregations