Search in sources :

Example 31 with DiscoveryEvent

use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.

the class IgniteSlowClientDetectionSelfTest method testSlowClient.

/**
     * @throws Exception If failed.
     */
public void testSlowClient() throws Exception {
    final IgniteEx slowClient = grid(nodeCount() - 1);
    final ClusterNode slowClientNode = slowClient.localNode();
    final CountDownLatch evtSegmentedLatch = new CountDownLatch(1);
    slowClient.events().localListen(new IgnitePredicate<Event>() {

        @Override
        public boolean apply(Event evt) {
            assertEquals("Unexpected event: " + evt, evt.type(), EventType.EVT_NODE_SEGMENTED);
            DiscoveryEvent evt0 = (DiscoveryEvent) evt;
            assertEquals(slowClientNode, evt0.eventNode());
            assertEquals(5L, evt0.topologyVersion());
            evtSegmentedLatch.countDown();
            return false;
        }
    }, EventType.EVT_NODE_SEGMENTED);
    final CountDownLatch evtFailedLatch = new CountDownLatch(nodeCount() - 1);
    for (int i = 0; i < nodeCount() - 1; i++) {
        grid(i).events().localListen(new IgnitePredicate<Event>() {

            @Override
            public boolean apply(Event evt) {
                assertEquals("Unexpected event: " + evt, evt.type(), EventType.EVT_NODE_FAILED);
                DiscoveryEvent evt0 = (DiscoveryEvent) evt;
                assertEquals(slowClientNode, evt0.eventNode());
                assertEquals(6L, evt0.topologyVersion());
                assertEquals(4, evt0.topologyNodes().size());
                evtFailedLatch.countDown();
                return false;
            }
        }, EventType.EVT_NODE_FAILED);
    }
    assertTrue(slowClient.cluster().localNode().isClient());
    IgniteCache<Object, Object> cache = slowClient.getOrCreateCache(PARTITIONED);
    IgniteEx client0 = grid(nodeCount() - 2);
    assertTrue(client0.cluster().localNode().isClient());
    IgniteCache<Object, Object> cache0 = client0.getOrCreateCache(PARTITIONED);
    cache.query(new ContinuousQuery<>().setLocalListener(new Listener()));
    for (int i = 0; i < 100; i++) cache0.put(0, i);
    GridIoManager ioMgr = slowClient.context().io();
    TcpCommunicationSpi commSpi = (TcpCommunicationSpi) ((Object[]) U.field(ioMgr, "spis"))[0];
    GridNioServer nioSrvr = U.field(commSpi, "nioSrvr");
    GridTestUtils.setFieldValue(nioSrvr, "skipRead", true);
    // Initiate messages for client.
    for (int i = 0; i < 100; i++) cache0.put(0, new byte[10 * 1024]);
    boolean wait = GridTestUtils.waitForCondition(new GridAbsPredicate() {

        @Override
        public boolean apply() {
            return Ignition.state(slowClient.name()) == IgniteState.STOPPED_ON_SEGMENTATION;
        }
    }, getTestTimeout());
    assertTrue(wait);
    assertTrue("Failed to wait for client failed event", evtFailedLatch.await(5000, MILLISECONDS));
    assertTrue("Failed to wait for client segmented event", evtSegmentedLatch.await(5000, MILLISECONDS));
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) CacheEntryUpdatedListener(javax.cache.event.CacheEntryUpdatedListener) GridAbsPredicate(org.apache.ignite.internal.util.lang.GridAbsPredicate) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) CountDownLatch(java.util.concurrent.CountDownLatch) TcpCommunicationSpi(org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi) GridNioServer(org.apache.ignite.internal.util.nio.GridNioServer) ContinuousQuery(org.apache.ignite.cache.query.ContinuousQuery) GridIoManager(org.apache.ignite.internal.managers.communication.GridIoManager) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) Event(org.apache.ignite.events.Event)

Example 32 with DiscoveryEvent

use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.

the class GridDiscoveryManager method start.

/** {@inheritDoc} */
@Override
public void start(boolean activeOnStart) throws IgniteCheckedException {
    long totSysMemory = -1;
    try {
        totSysMemory = U.<Long>property(os, "totalPhysicalMemorySize");
    } catch (RuntimeException ignored) {
    // No-op.
    }
    ctx.addNodeAttribute(IgniteNodeAttributes.ATTR_PHY_RAM, totSysMemory);
    DiscoverySpi spi = getSpi();
    discoOrdered = discoOrdered();
    histSupported = historySupported();
    isLocDaemon = ctx.isDaemon();
    hasRslvrs = !ctx.config().isClientMode() && !F.isEmpty(ctx.config().getSegmentationResolvers());
    segChkFreq = ctx.config().getSegmentCheckFrequency();
    if (hasRslvrs) {
        if (segChkFreq < 0)
            throw new IgniteCheckedException("Segment check frequency cannot be negative: " + segChkFreq);
        if (segChkFreq > 0 && segChkFreq < 2000)
            U.warn(log, "Configuration parameter 'segmentCheckFrequency' is too low " + "(at least 2000 ms recommended): " + segChkFreq);
        int segResAttemp = ctx.config().getSegmentationResolveAttempts();
        if (segResAttemp < 1)
            throw new IgniteCheckedException("Segment resolve attempts cannot be negative or zero: " + segResAttemp);
        checkSegmentOnStart();
    }
    metricsUpdateTask = ctx.timeout().schedule(new MetricsUpdater(), METRICS_UPDATE_FREQ, METRICS_UPDATE_FREQ);
    spi.setMetricsProvider(createMetricsProvider());
    if (ctx.security().enabled()) {
        if (isSecurityCompatibilityMode())
            ctx.addNodeAttribute(ATTR_SECURITY_COMPATIBILITY_MODE, true);
        spi.setAuthenticator(new DiscoverySpiNodeAuthenticator() {

            @Override
            public SecurityContext authenticateNode(ClusterNode node, SecurityCredentials cred) {
                try {
                    return ctx.security().authenticateNode(node, cred);
                } catch (IgniteCheckedException e) {
                    throw U.convertException(e);
                }
            }

            @Override
            public boolean isGlobalNodeAuthentication() {
                return ctx.security().isGlobalNodeAuthentication();
            }
        });
    }
    spi.setListener(new DiscoverySpiListener() {

        private long gridStartTime;

        /** {@inheritDoc} */
        @Override
        public void onLocalNodeInitialized(ClusterNode locNode) {
            for (IgniteInClosure<ClusterNode> lsnr : localNodeInitLsnrs) lsnr.apply(locNode);
        }

        @Override
        public void onDiscovery(final int type, final long topVer, final ClusterNode node, final Collection<ClusterNode> topSnapshot, final Map<Long, Collection<ClusterNode>> snapshots, @Nullable DiscoverySpiCustomMessage spiCustomMsg) {
            DiscoveryCustomMessage customMsg = spiCustomMsg == null ? null : ((CustomMessageWrapper) spiCustomMsg).delegate();
            if (skipMessage(type, customMsg))
                return;
            final ClusterNode locNode = localNode();
            if (snapshots != null)
                topHist = snapshots;
            boolean verChanged;
            if (type == EVT_NODE_METRICS_UPDATED)
                verChanged = false;
            else {
                if (type != EVT_NODE_SEGMENTED && type != EVT_CLIENT_NODE_DISCONNECTED && type != EVT_CLIENT_NODE_RECONNECTED && type != DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT) {
                    minorTopVer = 0;
                    verChanged = true;
                } else
                    verChanged = false;
            }
            if (type == EVT_NODE_FAILED || type == EVT_NODE_LEFT) {
                for (DiscoCache c : discoCacheHist.values()) c.updateAlives(node);
                updateClientNodes(node.id());
            }
            final AffinityTopologyVersion nextTopVer;
            if (type == DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT) {
                assert customMsg != null;
                boolean incMinorTopVer = ctx.cache().onCustomEvent(customMsg, new AffinityTopologyVersion(topVer, minorTopVer));
                if (incMinorTopVer) {
                    minorTopVer++;
                    verChanged = true;
                }
                nextTopVer = new AffinityTopologyVersion(topVer, minorTopVer);
                if (verChanged)
                    ctx.cache().onDiscoveryEvent(type, node, nextTopVer);
            } else {
                nextTopVer = new AffinityTopologyVersion(topVer, minorTopVer);
                ctx.cache().onDiscoveryEvent(type, node, nextTopVer);
            }
            if (type == DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT) {
                for (Class cls = customMsg.getClass(); cls != null; cls = cls.getSuperclass()) {
                    List<CustomEventListener<DiscoveryCustomMessage>> list = customEvtLsnrs.get(cls);
                    if (list != null) {
                        for (CustomEventListener<DiscoveryCustomMessage> lsnr : list) {
                            try {
                                lsnr.onCustomEvent(nextTopVer, node, customMsg);
                            } catch (Exception e) {
                                U.error(log, "Failed to notify direct custom event listener: " + customMsg, e);
                            }
                        }
                    }
                }
            }
            final DiscoCache discoCache;
            // event notifications, since SPI notifies manager about all events from this listener.
            if (verChanged) {
                discoCache = createDiscoCache(locNode, topSnapshot);
                discoCacheHist.put(nextTopVer, discoCache);
                boolean set = updateTopologyVersionIfGreater(nextTopVer, discoCache);
                assert set || topVer == 0 : "Topology version has not been updated [this.topVer=" + topSnap + ", topVer=" + topVer + ", node=" + node + ", evt=" + U.gridEventName(type) + ']';
            } else
                // Current version.
                discoCache = discoCache();
            // If this is a local join event, just save it and do not notify listeners.
            if (type == EVT_NODE_JOINED && node.id().equals(locNode.id())) {
                if (gridStartTime == 0)
                    gridStartTime = getSpi().getGridStartTime();
                updateTopologyVersionIfGreater(new AffinityTopologyVersion(locNode.order()), discoCache);
                startLatch.countDown();
                DiscoveryEvent discoEvt = new DiscoveryEvent();
                discoEvt.node(ctx.discovery().localNode());
                discoEvt.eventNode(node);
                discoEvt.type(EVT_NODE_JOINED);
                discoEvt.topologySnapshot(topVer, new ArrayList<>(F.view(topSnapshot, FILTER_DAEMON)));
                locJoin.onDone(new T2<>(discoEvt, discoCache));
                return;
            } else if (type == EVT_CLIENT_NODE_DISCONNECTED) {
                assert locNode.isClient() : locNode;
                assert node.isClient() : node;
                ((IgniteKernal) ctx.grid()).onDisconnected();
                locJoin = new GridFutureAdapter<>();
                registeredCaches.clear();
                for (AffinityTopologyVersion histVer : discoCacheHist.keySet()) {
                    Object rmvd = discoCacheHist.remove(histVer);
                    assert rmvd != null : histVer;
                }
                topHist.clear();
                topSnap.set(new Snapshot(AffinityTopologyVersion.ZERO, createDiscoCache(locNode, Collections.<ClusterNode>emptySet())));
            } else if (type == EVT_CLIENT_NODE_RECONNECTED) {
                assert locNode.isClient() : locNode;
                assert node.isClient() : node;
                boolean clusterRestarted = gridStartTime != getSpi().getGridStartTime();
                gridStartTime = getSpi().getGridStartTime();
                ((IgniteKernal) ctx.grid()).onReconnected(clusterRestarted);
                ctx.cluster().clientReconnectFuture().listen(new CI1<IgniteFuture<?>>() {

                    @Override
                    public void apply(IgniteFuture<?> fut) {
                        try {
                            fut.get();
                            discoWrk.addEvent(type, nextTopVer, node, discoCache, topSnapshot, null);
                        } catch (IgniteException ignore) {
                        // No-op.
                        }
                    }
                });
                return;
            }
            if (type == EVT_CLIENT_NODE_DISCONNECTED || type == EVT_NODE_SEGMENTED || !ctx.clientDisconnected())
                discoWrk.addEvent(type, nextTopVer, node, discoCache, topSnapshot, customMsg);
        }
    });
    spi.setDataExchange(new DiscoverySpiDataExchange() {

        @Override
        public DiscoveryDataBag collect(DiscoveryDataBag dataBag) {
            assert dataBag != null;
            assert dataBag.joiningNodeId() != null;
            if (ctx.localNodeId().equals(dataBag.joiningNodeId())) {
                for (GridComponent c : ctx.components()) c.collectJoiningNodeData(dataBag);
            } else {
                for (GridComponent c : ctx.components()) c.collectGridNodeData(dataBag);
            }
            return dataBag;
        }

        @Override
        public void onExchange(DiscoveryDataBag dataBag) {
            if (ctx.localNodeId().equals(dataBag.joiningNodeId())) {
                //NodeAdded msg reached joining node after round-trip over the ring
                for (GridComponent c : ctx.components()) {
                    if (c.discoveryDataType() != null)
                        c.onGridDataReceived(dataBag.gridDiscoveryData(c.discoveryDataType().ordinal()));
                }
            } else {
                //discovery data from newly joined node has to be applied to the current old node
                for (GridComponent c : ctx.components()) {
                    if (c.discoveryDataType() != null) {
                        JoiningNodeDiscoveryData data = dataBag.newJoinerDiscoveryData(c.discoveryDataType().ordinal());
                        if (data != null)
                            c.onJoiningNodeDataReceived(data);
                    }
                }
            }
        }
    });
    startSpi();
    registeredDiscoSpi = true;
    try {
        U.await(startLatch);
    } catch (IgniteInterruptedException e) {
        throw new IgniteCheckedException("Failed to start discovery manager (thread has been interrupted).", e);
    }
    // Start segment check worker only if frequency is greater than 0.
    if (hasRslvrs && segChkFreq > 0) {
        segChkWrk = new SegmentCheckWorker();
        segChkThread = new IgniteThread(segChkWrk);
        segChkThread.start();
    }
    locNode = spi.getLocalNode();
    checkAttributes(discoCache().remoteNodes());
    ctx.service().initCompatibilityMode(discoCache().remoteNodes());
    // Start discovery worker.
    new IgniteThread(discoWrk).start();
    if (log.isDebugEnabled())
        log.debug(startInfo());
}
Also used : GridComponent(org.apache.ignite.internal.GridComponent) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) IgniteFuture(org.apache.ignite.lang.IgniteFuture) CI1(org.apache.ignite.internal.util.typedef.CI1) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) JoiningNodeDiscoveryData(org.apache.ignite.spi.discovery.DiscoveryDataBag.JoiningNodeDiscoveryData) DiscoveryDataBag(org.apache.ignite.spi.discovery.DiscoveryDataBag) IgniteException(org.apache.ignite.IgniteException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) T2(org.apache.ignite.internal.util.typedef.T2) ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteKernal(org.apache.ignite.internal.IgniteKernal) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) DiscoverySpiNodeAuthenticator(org.apache.ignite.spi.discovery.DiscoverySpiNodeAuthenticator) IgniteInterruptedException(org.apache.ignite.IgniteInterruptedException) DiscoverySpiListener(org.apache.ignite.spi.discovery.DiscoverySpiListener) IgniteClientDisconnectedException(org.apache.ignite.IgniteClientDisconnectedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteSpiException(org.apache.ignite.spi.IgniteSpiException) IgniteInterruptedException(org.apache.ignite.IgniteInterruptedException) IgniteClientDisconnectedCheckedException(org.apache.ignite.internal.IgniteClientDisconnectedCheckedException) IgniteException(org.apache.ignite.IgniteException) SecurityCredentials(org.apache.ignite.plugin.security.SecurityCredentials) DiscoverySpiCustomMessage(org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage) ClusterMetricsSnapshot(org.apache.ignite.internal.ClusterMetricsSnapshot) DiscoverySpiDataExchange(org.apache.ignite.spi.discovery.DiscoverySpiDataExchange) DiscoverySpi(org.apache.ignite.spi.discovery.DiscoverySpi) TcpDiscoverySpi(org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi) SecurityContext(org.apache.ignite.internal.processors.security.SecurityContext) AtomicLong(java.util.concurrent.atomic.AtomicLong) IgniteInClosure(org.apache.ignite.lang.IgniteInClosure) Collection(java.util.Collection) IgniteThread(org.apache.ignite.thread.IgniteThread)

Example 33 with DiscoveryEvent

use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.

the class GridEventStorageManager method query.

/**
     * @param p Grid event predicate.
     * @param nodes Collection of nodes.
     * @param timeout Maximum time to wait for result, if {@code 0}, then wait until result is received.
     * @return Collection of events.
     * @throws IgniteCheckedException Thrown in case of any errors.
     */
@SuppressWarnings({ "SynchronizationOnLocalVariableOrMethodParameter", "deprecation" })
private <T extends Event> List<T> query(IgnitePredicate<T> p, Collection<? extends ClusterNode> nodes, long timeout) throws IgniteCheckedException {
    assert p != null;
    assert nodes != null;
    if (nodes.isEmpty()) {
        U.warn(log, "Failed to query events for empty nodes collection.");
        return Collections.emptyList();
    }
    GridIoManager ioMgr = ctx.io();
    final List<T> evts = new ArrayList<>();
    final AtomicReference<Throwable> err = new AtomicReference<>();
    final Set<UUID> uids = new HashSet<>();
    final Object qryMux = new Object();
    for (ClusterNode node : nodes) uids.add(node.id());
    GridLocalEventListener evtLsnr = new GridLocalEventListener() {

        @Override
        public void onEvent(Event evt) {
            assert evt instanceof DiscoveryEvent;
            synchronized (qryMux) {
                uids.remove(((DiscoveryEvent) evt).eventNode().id());
                if (uids.isEmpty())
                    qryMux.notifyAll();
            }
        }
    };
    GridMessageListener resLsnr = new GridMessageListener() {

        @SuppressWarnings("deprecation")
        @Override
        public void onMessage(UUID nodeId, Object msg) {
            assert nodeId != null;
            assert msg != null;
            if (!(msg instanceof GridEventStorageMessage)) {
                U.error(log, "Received unknown message: " + msg);
                return;
            }
            GridEventStorageMessage res = (GridEventStorageMessage) msg;
            try {
                if (res.eventsBytes() != null)
                    res.events(U.<Collection<Event>>unmarshal(marsh, res.eventsBytes(), U.resolveClassLoader(ctx.config())));
                if (res.exceptionBytes() != null)
                    res.exception(U.<Throwable>unmarshal(marsh, res.exceptionBytes(), U.resolveClassLoader(ctx.config())));
            } catch (IgniteCheckedException e) {
                U.error(log, "Failed to unmarshal events query response: " + msg, e);
                return;
            }
            synchronized (qryMux) {
                if (uids.remove(nodeId)) {
                    if (res.events() != null)
                        evts.addAll((Collection<T>) res.events());
                } else
                    U.warn(log, "Received duplicate response (ignoring) [nodeId=" + nodeId + ", msg=" + res + ']');
                if (res.exception() != null)
                    err.set(res.exception());
                if (uids.isEmpty() || err.get() != null)
                    qryMux.notifyAll();
            }
        }
    };
    Object resTopic = TOPIC_EVENT.topic(IgniteUuid.fromUuid(ctx.localNodeId()));
    try {
        addLocalEventListener(evtLsnr, new int[] { EVT_NODE_LEFT, EVT_NODE_FAILED });
        ioMgr.addMessageListener(resTopic, resLsnr);
        byte[] serFilter = U.marshal(marsh, p);
        GridDeployment dep = ctx.deploy().deploy(p.getClass(), U.detectClassLoader(p.getClass()));
        if (dep == null)
            throw new IgniteDeploymentCheckedException("Failed to deploy event filter: " + p);
        GridEventStorageMessage msg = new GridEventStorageMessage(resTopic, serFilter, p.getClass().getName(), dep.classLoaderId(), dep.deployMode(), dep.userVersion(), dep.participants());
        sendMessage(nodes, TOPIC_EVENT, msg, PUBLIC_POOL);
        if (timeout == 0)
            timeout = Long.MAX_VALUE;
        long now = U.currentTimeMillis();
        // Account for overflow of long value.
        long endTime = now + timeout <= 0 ? Long.MAX_VALUE : now + timeout;
        long delta = timeout;
        Collection<UUID> uidsCp = null;
        synchronized (qryMux) {
            try {
                while (!uids.isEmpty() && err.get() == null && delta > 0) {
                    qryMux.wait(delta);
                    delta = endTime - U.currentTimeMillis();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new IgniteCheckedException("Got interrupted while waiting for event query responses.", e);
            }
            if (err.get() != null)
                throw new IgniteCheckedException("Failed to query events due to exception on remote node.", err.get());
            if (!uids.isEmpty())
                uidsCp = new LinkedList<>(uids);
        }
        // Outside of synchronization.
        if (uidsCp != null) {
            for (Iterator<UUID> iter = uidsCp.iterator(); iter.hasNext(); ) // Ignore nodes that have left the grid.
            if (ctx.discovery().node(iter.next()) == null)
                iter.remove();
            if (!uidsCp.isEmpty())
                throw new IgniteCheckedException("Failed to receive event query response from following nodes: " + uidsCp);
        }
    } finally {
        ioMgr.removeMessageListener(resTopic, resLsnr);
        removeLocalEventListener(evtLsnr);
    }
    return evts;
}
Also used : GridMessageListener(org.apache.ignite.internal.managers.communication.GridMessageListener) ArrayList(java.util.ArrayList) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) EVT_NODE_LEFT(org.apache.ignite.events.EventType.EVT_NODE_LEFT) EVT_DISCOVERY_CUSTOM_EVT(org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT) LT(org.apache.ignite.internal.util.typedef.internal.LT) TOPIC_EVENT(org.apache.ignite.internal.GridTopic.TOPIC_EVENT) UUID(java.util.UUID) GridConcurrentLinkedHashSet(org.apache.ignite.internal.util.GridConcurrentLinkedHashSet) HashSet(java.util.HashSet) ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteDeploymentCheckedException(org.apache.ignite.internal.IgniteDeploymentCheckedException) AtomicReference(java.util.concurrent.atomic.AtomicReference) LinkedList(java.util.LinkedList) GridDeployment(org.apache.ignite.internal.managers.deployment.GridDeployment) GridIoManager(org.apache.ignite.internal.managers.communication.GridIoManager) Event(org.apache.ignite.events.Event) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) Collection(java.util.Collection)

Example 34 with DiscoveryEvent

use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.

the class GridIoManager method onKernalStart0.

/** {@inheritDoc} */
@SuppressWarnings({ "deprecation", "SynchronizationOnLocalVariableOrMethodParameter" })
@Override
public void onKernalStart0() throws IgniteCheckedException {
    discoLsnr = new GridLocalEventListener() {

        @SuppressWarnings({ "TooBroadScope", "fallthrough" })
        @Override
        public void onEvent(Event evt) {
            assert evt instanceof DiscoveryEvent : "Invalid event: " + evt;
            DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
            UUID nodeId = discoEvt.eventNode().id();
            switch(evt.type()) {
                case EVT_NODE_JOINED:
                    // We can't receive messages from undiscovered nodes.
                    assert waitMap.get(nodeId) == null;
                    break;
                case EVT_NODE_LEFT:
                case EVT_NODE_FAILED:
                    for (Map.Entry<Object, ConcurrentMap<UUID, GridCommunicationMessageSet>> e : msgSetMap.entrySet()) {
                        ConcurrentMap<UUID, GridCommunicationMessageSet> map = e.getValue();
                        GridCommunicationMessageSet set;
                        boolean empty;
                        synchronized (map) {
                            set = map.remove(nodeId);
                            empty = map.isEmpty();
                        }
                        if (set != null) {
                            if (log.isDebugEnabled())
                                log.debug("Removed message set due to node leaving grid: " + set);
                            // Unregister timeout listener.
                            ctx.timeout().removeTimeoutObject(set);
                            // Node may still send stale messages for this topic
                            // even after discovery notification is done.
                            closedTopics.add(set.topic());
                        }
                        if (empty)
                            msgSetMap.remove(e.getKey(), map);
                    }
                    // Clean up delayed and ordered messages (need exclusive lock).
                    lock.writeLock().lock();
                    try {
                        ConcurrentLinkedDeque8<DelayedMessage> waitList = waitMap.remove(nodeId);
                        if (log.isDebugEnabled())
                            log.debug("Removed messages from discovery startup delay list " + "(sender node left topology): " + waitList);
                    } finally {
                        lock.writeLock().unlock();
                    }
                    break;
                default:
                    assert false : "Unexpected event: " + evt;
            }
        }
    };
    ctx.event().addLocalEventListener(discoLsnr, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_NODE_FAILED);
    // Make sure that there are no stale messages due to window between communication
    // manager start and kernal start.
    // 1. Process wait list.
    Collection<Collection<DelayedMessage>> delayedMsgs = new ArrayList<>();
    lock.writeLock().lock();
    try {
        started = true;
        for (Entry<UUID, ConcurrentLinkedDeque8<DelayedMessage>> e : waitMap.entrySet()) {
            if (ctx.discovery().node(e.getKey()) != null) {
                ConcurrentLinkedDeque8<DelayedMessage> waitList = waitMap.remove(e.getKey());
                if (log.isDebugEnabled())
                    log.debug("Processing messages from discovery startup delay list: " + waitList);
                if (waitList != null)
                    delayedMsgs.add(waitList);
            }
        }
    } finally {
        lock.writeLock().unlock();
    }
    // After write lock released.
    if (!delayedMsgs.isEmpty()) {
        for (Collection<DelayedMessage> col : delayedMsgs) for (DelayedMessage msg : col) commLsnr.onMessage(msg.nodeId(), msg.message(), msg.callback());
    }
    // 2. Process messages sets.
    for (Map.Entry<Object, ConcurrentMap<UUID, GridCommunicationMessageSet>> e : msgSetMap.entrySet()) {
        ConcurrentMap<UUID, GridCommunicationMessageSet> map = e.getValue();
        for (GridCommunicationMessageSet set : map.values()) {
            if (ctx.discovery().node(set.nodeId()) == null) {
                // All map modifications should be synced for consistency.
                boolean rmv;
                synchronized (map) {
                    rmv = map.remove(set.nodeId(), set);
                }
                if (rmv) {
                    if (log.isDebugEnabled())
                        log.debug("Removed message set due to node leaving grid: " + set);
                    // Unregister timeout listener.
                    ctx.timeout().removeTimeoutObject(set);
                }
            }
        }
        boolean rmv;
        synchronized (map) {
            rmv = map.isEmpty();
        }
        if (rmv) {
            msgSetMap.remove(e.getKey(), map);
            // Node may still send stale messages for this topic
            // even after discovery notification is done.
            closedTopics.add(e.getKey());
        }
    }
}
Also used : ConcurrentLinkedDeque8(org.jsr166.ConcurrentLinkedDeque8) GridLocalEventListener(org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener) ConcurrentMap(java.util.concurrent.ConcurrentMap) ArrayList(java.util.ArrayList) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) Entry(java.util.Map.Entry) Event(org.apache.ignite.events.Event) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) Collection(java.util.Collection) GridTimeoutObject(org.apache.ignite.internal.processors.timeout.GridTimeoutObject) UUID(java.util.UUID) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 35 with DiscoveryEvent

use of org.apache.ignite.events.DiscoveryEvent in project ignite by apache.

the class GridDeploymentCommunication method sendResourceRequest.

/**
     * Sends request to the remote node and wait for response. If there is
     * no response until threshold time, method returns null.
     *
     *
     * @param rsrcName Resource name.
     * @param clsLdrId Class loader ID.
     * @param dstNode Remote node request should be sent to.
     * @param threshold Time in milliseconds when request is decided to
     *      be obsolete.
     * @return Either response value or {@code null} if timeout occurred.
     * @throws IgniteCheckedException Thrown if there is no connection with remote node.
     */
@SuppressWarnings({ "SynchronizationOnLocalVariableOrMethodParameter" })
GridDeploymentResponse sendResourceRequest(final String rsrcName, IgniteUuid clsLdrId, final ClusterNode dstNode, long threshold) throws IgniteCheckedException {
    assert rsrcName != null;
    assert dstNode != null;
    assert clsLdrId != null;
    Collection<UUID> nodeIds = activeReqNodeIds.get();
    if (nodeIds != null && nodeIds.contains(dstNode.id())) {
        if (log.isDebugEnabled())
            log.debug("Node attempts to load resource from one of the requesters " + "[rsrcName=" + rsrcName + ", dstNodeId=" + dstNode.id() + ", requesters=" + nodeIds + ']');
        GridDeploymentResponse fake = new GridDeploymentResponse();
        fake.success(false);
        fake.errorMessage("Node attempts to load resource from one of the requesters " + "[rsrcName=" + rsrcName + ", dstNodeId=" + dstNode.id() + ", requesters=" + nodeIds + ']');
        return fake;
    }
    Object resTopic = TOPIC_CLASSLOAD.topic(IgniteUuid.fromUuid(ctx.localNodeId()));
    GridDeploymentRequest req = new GridDeploymentRequest(resTopic, clsLdrId, rsrcName, false);
    // Send node IDs chain with request.
    req.nodeIds(nodeIds);
    final Object qryMux = new Object();
    final GridTuple<GridDeploymentResponse> res = new GridTuple<>();
    GridLocalEventListener discoLsnr = new GridLocalEventListener() {

        @Override
        public void onEvent(Event evt) {
            assert evt instanceof DiscoveryEvent;
            assert evt.type() == EVT_NODE_LEFT || evt.type() == EVT_NODE_FAILED;
            DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
            UUID nodeId = discoEvt.eventNode().id();
            if (!nodeId.equals(dstNode.id()))
                // Not a destination node.
                return;
            GridDeploymentResponse fake = new GridDeploymentResponse();
            String errMsg = "Originating node left grid (resource will not be peer loaded) " + "[nodeId=" + dstNode.id() + ", rsrc=" + rsrcName + ']';
            U.warn(log, errMsg);
            fake.success(false);
            fake.errorMessage(errMsg);
            // because originating node has left grid.
            synchronized (qryMux) {
                res.set(fake);
                qryMux.notifyAll();
            }
        }
    };
    GridMessageListener resLsnr = new GridMessageListener() {

        @Override
        public void onMessage(UUID nodeId, Object msg) {
            assert nodeId != null;
            assert msg != null;
            synchronized (qryMux) {
                if (!(msg instanceof GridDeploymentResponse)) {
                    U.error(log, "Received unknown peer class loading response [node=" + nodeId + ", msg=" + msg + ']');
                } else
                    res.set((GridDeploymentResponse) msg);
                qryMux.notifyAll();
            }
        }
    };
    try {
        ctx.io().addMessageListener(resTopic, resLsnr);
        // The destination node has potentially left grid here but in this case
        // Communication manager will throw the exception while sending message.
        ctx.event().addLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
        long start = U.currentTimeMillis();
        if (req.responseTopic() != null && !ctx.localNodeId().equals(dstNode.id()))
            req.responseTopicBytes(U.marshal(marsh, req.responseTopic()));
        ctx.io().sendToGridTopic(dstNode, TOPIC_CLASSLOAD, req, GridIoPolicy.P2P_POOL);
        if (log.isDebugEnabled())
            log.debug("Sent peer class loading request [node=" + dstNode.id() + ", req=" + req + ']');
        synchronized (qryMux) {
            try {
                long timeout = threshold - start;
                if (log.isDebugEnabled()) {
                    log.debug("Waiting for peer response from node [node=" + dstNode.id() + ", timeout=" + timeout + ']');
                }
                while (res.get() == null && timeout > 0) {
                    qryMux.wait(timeout);
                    timeout = threshold - U.currentTimeMillis();
                }
            } catch (InterruptedException e) {
                // Interrupt again to get it in the users code.
                Thread.currentThread().interrupt();
                throw new IgniteCheckedException("Got interrupted while waiting for response from node: " + dstNode.id(), e);
            }
        }
        if (res.get() == null) {
            U.warn(log, "Failed to receive peer response from node within duration [node=" + dstNode.id() + ", duration=" + (U.currentTimeMillis() - start) + ']');
        } else if (log.isDebugEnabled())
            log.debug("Received peer loading response [node=" + dstNode.id() + ", res=" + res.get() + ']');
        return res.get();
    } finally {
        ctx.event().removeLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
        ctx.io().removeMessageListener(resTopic, resLsnr);
    }
}
Also used : GridLocalEventListener(org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener) GridMessageListener(org.apache.ignite.internal.managers.communication.GridMessageListener) GridTuple(org.apache.ignite.internal.util.lang.GridTuple) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent) Event(org.apache.ignite.events.Event) UUID(java.util.UUID)

Aggregations

DiscoveryEvent (org.apache.ignite.events.DiscoveryEvent)68 Event (org.apache.ignite.events.Event)49 UUID (java.util.UUID)36 ClusterNode (org.apache.ignite.cluster.ClusterNode)27 GridLocalEventListener (org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener)22 Ignite (org.apache.ignite.Ignite)20 CountDownLatch (java.util.concurrent.CountDownLatch)19 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)14 ArrayList (java.util.ArrayList)11 Collection (java.util.Collection)10 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)10 List (java.util.List)9 GridMessageListener (org.apache.ignite.internal.managers.communication.GridMessageListener)9 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)8 JobEvent (org.apache.ignite.events.JobEvent)8 GridAffinityFunctionContextImpl (org.apache.ignite.internal.processors.affinity.GridAffinityFunctionContextImpl)7 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 IgniteException (org.apache.ignite.IgniteException)5 HashMap (java.util.HashMap)4