Search in sources :

Example 1 with GridTcpNioCommunicationClient

use of org.apache.ignite.internal.util.nio.GridTcpNioCommunicationClient in project ignite by apache.

the class TcpCommunicationSpi method reserveClient.

/**
     * Returns existing or just created client to node.
     *
     * @param node Node to which client should be open.
     * @param connIdx Connection index.
     * @return The existing or just created client.
     * @throws IgniteCheckedException Thrown if any exception occurs.
     */
private GridCommunicationClient reserveClient(ClusterNode node, int connIdx) throws IgniteCheckedException {
    assert node != null;
    assert (connIdx >= 0 && connIdx < connectionsPerNode) || !usePairedConnections(node) : connIdx;
    UUID nodeId = node.id();
    while (true) {
        GridCommunicationClient[] curClients = clients.get(nodeId);
        GridCommunicationClient client = curClients != null && connIdx < curClients.length ? curClients[connIdx] : null;
        if (client == null) {
            if (stopping)
                throw new IgniteSpiException("Node is stopping.");
            // Do not allow concurrent connects.
            GridFutureAdapter<GridCommunicationClient> fut = new ConnectFuture();
            ConnectionKey connKey = new ConnectionKey(nodeId, connIdx, -1);
            GridFutureAdapter<GridCommunicationClient> oldFut = clientFuts.putIfAbsent(connKey, fut);
            if (oldFut == null) {
                try {
                    GridCommunicationClient[] curClients0 = clients.get(nodeId);
                    GridCommunicationClient client0 = curClients0 != null && connIdx < curClients0.length ? curClients0[connIdx] : null;
                    if (client0 == null) {
                        client0 = createNioClient(node, connIdx);
                        if (client0 != null) {
                            addNodeClient(node, connIdx, client0);
                            if (client0 instanceof GridTcpNioCommunicationClient) {
                                GridTcpNioCommunicationClient tcpClient = ((GridTcpNioCommunicationClient) client0);
                                if (tcpClient.session().closeTime() > 0 && removeNodeClient(nodeId, client0)) {
                                    if (log.isDebugEnabled())
                                        log.debug("Session was closed after client creation, will retry " + "[node=" + node + ", client=" + client0 + ']');
                                    client0 = null;
                                }
                            }
                        } else
                            U.sleep(200);
                    }
                    fut.onDone(client0);
                } catch (Throwable e) {
                    fut.onDone(e);
                    if (e instanceof Error)
                        throw (Error) e;
                } finally {
                    clientFuts.remove(connKey, fut);
                }
            } else
                fut = oldFut;
            client = fut.get();
            if (client == null)
                continue;
            if (getSpiContext().node(nodeId) == null) {
                if (removeNodeClient(nodeId, client))
                    client.forceClose();
                throw new IgniteSpiException("Destination node is not in topology: " + node.id());
            }
        }
        assert connIdx == client.connectionIndex() : client;
        if (client.reserve())
            return client;
        else
            // Client has just been closed by idle worker. Help it and try again.
            removeNodeClient(nodeId, client);
    }
}
Also used : IgniteSpiException(org.apache.ignite.spi.IgniteSpiException) UUID(java.util.UUID) GridCommunicationClient(org.apache.ignite.internal.util.nio.GridCommunicationClient) GridTcpNioCommunicationClient(org.apache.ignite.internal.util.nio.GridTcpNioCommunicationClient)

Example 2 with GridTcpNioCommunicationClient

use of org.apache.ignite.internal.util.nio.GridTcpNioCommunicationClient in project ignite by apache.

the class IgniteCacheMessageRecoveryAbstractTest method closeSessions.

/**
     * @param ignite Node.
     * @throws Exception If failed.
     * @return {@code True} if closed at least one session.
     */
static boolean closeSessions(Ignite ignite) throws Exception {
    TcpCommunicationSpi commSpi = (TcpCommunicationSpi) ignite.configuration().getCommunicationSpi();
    Map<UUID, GridCommunicationClient[]> clients = U.field(commSpi, "clients");
    boolean closed = false;
    for (GridCommunicationClient[] clients0 : clients.values()) {
        for (GridCommunicationClient client : clients0) {
            if (client != null) {
                GridTcpNioCommunicationClient client0 = (GridTcpNioCommunicationClient) client;
                GridNioSession ses = client0.session();
                ses.close();
                closed = true;
            }
        }
    }
    return closed;
}
Also used : GridNioSession(org.apache.ignite.internal.util.nio.GridNioSession) UUID(java.util.UUID) GridCommunicationClient(org.apache.ignite.internal.util.nio.GridCommunicationClient) GridTcpNioCommunicationClient(org.apache.ignite.internal.util.nio.GridTcpNioCommunicationClient) TcpCommunicationSpi(org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi)

Example 3 with GridTcpNioCommunicationClient

use of org.apache.ignite.internal.util.nio.GridTcpNioCommunicationClient in project ignite by apache.

the class TcpCommunicationSpi method createTcpClient.

/**
     * Establish TCP connection to remote node and returns client.
     *
     * @param node Remote node.
     * @param connIdx Connection index.
     * @return Client.
     * @throws IgniteCheckedException If failed.
     */
protected GridCommunicationClient createTcpClient(ClusterNode node, int connIdx) throws IgniteCheckedException {
    Collection<String> rmtAddrs0 = node.attribute(createSpiAttributeName(ATTR_ADDRS));
    Collection<String> rmtHostNames0 = node.attribute(createSpiAttributeName(ATTR_HOST_NAMES));
    Integer boundPort = node.attribute(createSpiAttributeName(ATTR_PORT));
    Collection<InetSocketAddress> extAddrs = node.attribute(createSpiAttributeName(ATTR_EXT_ADDRS));
    boolean isRmtAddrsExist = (!F.isEmpty(rmtAddrs0) && boundPort != null);
    boolean isExtAddrsExist = !F.isEmpty(extAddrs);
    if (!isRmtAddrsExist && !isExtAddrsExist)
        throw new IgniteCheckedException("Failed to send message to the destination node. Node doesn't have any " + "TCP communication addresses or mapped external addresses. Check configuration and make sure " + "that you use the same communication SPI on all nodes. Remote node id: " + node.id());
    LinkedHashSet<InetSocketAddress> addrs;
    // Try to connect first on bound addresses.
    if (isRmtAddrsExist) {
        List<InetSocketAddress> addrs0 = new ArrayList<>(U.toSocketAddresses(rmtAddrs0, rmtHostNames0, boundPort));
        boolean sameHost = U.sameMacs(getSpiContext().localNode(), node);
        Collections.sort(addrs0, U.inetAddressesComparator(sameHost));
        addrs = new LinkedHashSet<>(addrs0);
    } else
        addrs = new LinkedHashSet<>();
    // Then on mapped external addresses.
    if (isExtAddrsExist)
        addrs.addAll(extAddrs);
    Set<InetAddress> allInetAddrs = U.newHashSet(addrs.size());
    for (InetSocketAddress addr : addrs) {
        // Skip unresolved as addr.getAddress() can return null.
        if (!addr.isUnresolved())
            allInetAddrs.add(addr.getAddress());
    }
    List<InetAddress> reachableInetAddrs = U.filterReachable(allInetAddrs);
    if (reachableInetAddrs.size() < allInetAddrs.size()) {
        LinkedHashSet<InetSocketAddress> addrs0 = U.newLinkedHashSet(addrs.size());
        List<InetSocketAddress> unreachableInetAddr = new ArrayList<>(allInetAddrs.size() - reachableInetAddrs.size());
        for (InetSocketAddress addr : addrs) {
            if (reachableInetAddrs.contains(addr.getAddress()))
                addrs0.add(addr);
            else
                unreachableInetAddr.add(addr);
        }
        addrs0.addAll(unreachableInetAddr);
        addrs = addrs0;
    }
    if (log.isDebugEnabled())
        log.debug("Addresses to connect for node [rmtNode=" + node.id() + ", addrs=" + addrs.toString() + ']');
    boolean conn = false;
    GridCommunicationClient client = null;
    IgniteCheckedException errs = null;
    int connectAttempts = 1;
    for (InetSocketAddress addr : addrs) {
        long connTimeout0 = connTimeout;
        int attempt = 1;
        IgniteSpiOperationTimeoutHelper timeoutHelper = new IgniteSpiOperationTimeoutHelper(this, !node.isClient());
        while (!conn) {
            // Reconnection on handshake timeout.
            try {
                SocketChannel ch = SocketChannel.open();
                ch.configureBlocking(true);
                ch.socket().setTcpNoDelay(tcpNoDelay);
                ch.socket().setKeepAlive(true);
                if (sockRcvBuf > 0)
                    ch.socket().setReceiveBufferSize(sockRcvBuf);
                if (sockSndBuf > 0)
                    ch.socket().setSendBufferSize(sockSndBuf);
                if (getSpiContext().node(node.id()) == null) {
                    U.closeQuiet(ch);
                    throw new ClusterTopologyCheckedException("Failed to send message " + "(node left topology): " + node);
                }
                ConnectionKey connKey = new ConnectionKey(node.id(), connIdx, -1);
                GridNioRecoveryDescriptor recoveryDesc = outRecoveryDescriptor(node, connKey);
                if (!recoveryDesc.reserve()) {
                    U.closeQuiet(ch);
                    return null;
                }
                long rcvCnt = -1;
                Map<Integer, Object> meta = new HashMap<>();
                GridSslMeta sslMeta = null;
                try {
                    ch.socket().connect(addr, (int) timeoutHelper.nextTimeoutChunk(connTimeout));
                    if (isSslEnabled()) {
                        meta.put(SSL_META.ordinal(), sslMeta = new GridSslMeta());
                        SSLEngine sslEngine = ignite.configuration().getSslContextFactory().create().createSSLEngine();
                        sslEngine.setUseClientMode(true);
                        sslMeta.sslEngine(sslEngine);
                    }
                    Integer handshakeConnIdx = connIdx;
                    rcvCnt = safeHandshake(ch, recoveryDesc, node.id(), timeoutHelper.nextTimeoutChunk(connTimeout0), sslMeta, handshakeConnIdx);
                    if (rcvCnt == -1)
                        return null;
                } finally {
                    if (recoveryDesc != null && rcvCnt == -1)
                        recoveryDesc.release();
                }
                try {
                    meta.put(CONN_IDX_META, connKey);
                    if (recoveryDesc != null) {
                        recoveryDesc.onHandshake(rcvCnt);
                        meta.put(-1, recoveryDesc);
                    }
                    GridNioSession ses = nioSrvr.createSession(ch, meta).get();
                    client = new GridTcpNioCommunicationClient(connIdx, ses, log);
                    conn = true;
                } finally {
                    if (!conn) {
                        if (recoveryDesc != null)
                            recoveryDesc.release();
                    }
                }
            } catch (HandshakeTimeoutException | IgniteSpiOperationTimeoutException e) {
                if (client != null) {
                    client.forceClose();
                    client = null;
                }
                if (failureDetectionTimeoutEnabled() && (e instanceof HandshakeTimeoutException || timeoutHelper.checkFailureTimeoutReached(e))) {
                    String msg = "Handshake timed out (failure detection timeout is reached) " + "[failureDetectionTimeout=" + failureDetectionTimeout() + ", addr=" + addr + ']';
                    onException(msg, e);
                    if (log.isDebugEnabled())
                        log.debug(msg);
                    if (errs == null)
                        errs = new IgniteCheckedException("Failed to connect to node (is node still alive?). " + "Make sure that each ComputeTask and cache Transaction has a timeout set " + "in order to prevent parties from waiting forever in case of network issues " + "[nodeId=" + node.id() + ", addrs=" + addrs + ']');
                    errs.addSuppressed(new IgniteCheckedException("Failed to connect to address: " + addr, e));
                    break;
                }
                assert !failureDetectionTimeoutEnabled();
                onException("Handshake timed out (will retry with increased timeout) [timeout=" + connTimeout0 + ", addr=" + addr + ']', e);
                if (log.isDebugEnabled())
                    log.debug("Handshake timed out (will retry with increased timeout) [timeout=" + connTimeout0 + ", addr=" + addr + ", err=" + e + ']');
                if (attempt == reconCnt || connTimeout0 > maxConnTimeout) {
                    if (log.isDebugEnabled())
                        log.debug("Handshake timedout (will stop attempts to perform the handshake) " + "[timeout=" + connTimeout0 + ", maxConnTimeout=" + maxConnTimeout + ", attempt=" + attempt + ", reconCnt=" + reconCnt + ", err=" + e.getMessage() + ", addr=" + addr + ']');
                    if (errs == null)
                        errs = new IgniteCheckedException("Failed to connect to node (is node still alive?). " + "Make sure that each ComputeTask and cache Transaction has a timeout set " + "in order to prevent parties from waiting forever in case of network issues " + "[nodeId=" + node.id() + ", addrs=" + addrs + ']');
                    errs.addSuppressed(new IgniteCheckedException("Failed to connect to address: " + addr, e));
                    break;
                } else {
                    attempt++;
                    connTimeout0 *= 2;
                // Continue loop.
                }
            } catch (Exception e) {
                if (client != null) {
                    client.forceClose();
                    client = null;
                }
                onException("Client creation failed [addr=" + addr + ", err=" + e + ']', e);
                if (log.isDebugEnabled())
                    log.debug("Client creation failed [addr=" + addr + ", err=" + e + ']');
                boolean failureDetThrReached = timeoutHelper.checkFailureTimeoutReached(e);
                if (failureDetThrReached)
                    LT.warn(log, "Connect timed out (consider increasing 'failureDetectionTimeout' " + "configuration property) [addr=" + addr + ", failureDetectionTimeout=" + failureDetectionTimeout() + ']');
                else if (X.hasCause(e, SocketTimeoutException.class))
                    LT.warn(log, "Connect timed out (consider increasing 'connTimeout' " + "configuration property) [addr=" + addr + ", connTimeout=" + connTimeout + ']');
                if (errs == null)
                    errs = new IgniteCheckedException("Failed to connect to node (is node still alive?). " + "Make sure that each ComputeTask and cache Transaction has a timeout set " + "in order to prevent parties from waiting forever in case of network issues " + "[nodeId=" + node.id() + ", addrs=" + addrs + ']');
                errs.addSuppressed(new IgniteCheckedException("Failed to connect to address: " + addr, e));
                // Reconnect for the second time, if connection is not established.
                if (!failureDetThrReached && connectAttempts < 2 && (e instanceof ConnectException || X.hasCause(e, ConnectException.class))) {
                    connectAttempts++;
                    continue;
                }
                break;
            }
        }
        if (conn)
            break;
    }
    if (client == null) {
        assert errs != null;
        if (X.hasCause(errs, ConnectException.class))
            LT.warn(log, "Failed to connect to a remote node " + "(make sure that destination node is alive and " + "operating system firewall is disabled on local and remote hosts) " + "[addrs=" + addrs + ']');
        if (getSpiContext().node(node.id()) != null && (CU.clientNode(node) || !CU.clientNode(getLocalNode())) && X.hasCause(errs, ConnectException.class, SocketTimeoutException.class, HandshakeTimeoutException.class, IgniteSpiOperationTimeoutException.class)) {
            LT.warn(log, "TcpCommunicationSpi failed to establish connection to node, node will be dropped from " + "cluster [" + "rmtNode=" + node + ", err=" + errs + ", connectErrs=" + Arrays.toString(errs.getSuppressed()) + ']');
            getSpiContext().failNode(node.id(), "TcpCommunicationSpi failed to establish connection to node [" + "rmtNode=" + node + ", errs=" + errs + ", connectErrs=" + Arrays.toString(errs.getSuppressed()) + ']');
        }
        throw errs;
    }
    return client;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SocketChannel(java.nio.channels.SocketChannel) GridNioSession(org.apache.ignite.internal.util.nio.GridNioSession) HashMap(java.util.HashMap) InetSocketAddress(java.net.InetSocketAddress) SSLEngine(javax.net.ssl.SSLEngine) ArrayList(java.util.ArrayList) GridSslMeta(org.apache.ignite.internal.util.nio.ssl.GridSslMeta) GridTcpNioCommunicationClient(org.apache.ignite.internal.util.nio.GridTcpNioCommunicationClient) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteSpiOperationTimeoutException(org.apache.ignite.spi.IgniteSpiOperationTimeoutException) ConnectException(java.net.ConnectException) GridCommunicationClient(org.apache.ignite.internal.util.nio.GridCommunicationClient) IpcEndpoint(org.apache.ignite.internal.util.ipc.IpcEndpoint) IpcSharedMemoryServerEndpoint(org.apache.ignite.internal.util.ipc.shmem.IpcSharedMemoryServerEndpoint) IgniteClientDisconnectedException(org.apache.ignite.IgniteClientDisconnectedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) SSLException(javax.net.ssl.SSLException) IgniteSpiOperationTimeoutException(org.apache.ignite.spi.IgniteSpiOperationTimeoutException) IgniteSpiException(org.apache.ignite.spi.IgniteSpiException) SocketTimeoutException(java.net.SocketTimeoutException) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) ConnectException(java.net.ConnectException) IpcOutOfSystemResourcesException(org.apache.ignite.internal.util.ipc.shmem.IpcOutOfSystemResourcesException) IOException(java.io.IOException) IgniteClientDisconnectedCheckedException(org.apache.ignite.internal.IgniteClientDisconnectedCheckedException) IgniteException(org.apache.ignite.IgniteException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IgniteSpiOperationTimeoutHelper(org.apache.ignite.spi.IgniteSpiOperationTimeoutHelper) SocketTimeoutException(java.net.SocketTimeoutException) GridNioRecoveryDescriptor(org.apache.ignite.internal.util.nio.GridNioRecoveryDescriptor) IgniteSpiTimeoutObject(org.apache.ignite.spi.IgniteSpiTimeoutObject) InetAddress(java.net.InetAddress) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Aggregations

GridCommunicationClient (org.apache.ignite.internal.util.nio.GridCommunicationClient)3 GridTcpNioCommunicationClient (org.apache.ignite.internal.util.nio.GridTcpNioCommunicationClient)3 UUID (java.util.UUID)2 GridNioSession (org.apache.ignite.internal.util.nio.GridNioSession)2 IgniteSpiException (org.apache.ignite.spi.IgniteSpiException)2 IOException (java.io.IOException)1 ConnectException (java.net.ConnectException)1 InetAddress (java.net.InetAddress)1 InetSocketAddress (java.net.InetSocketAddress)1 SocketTimeoutException (java.net.SocketTimeoutException)1 SocketChannel (java.nio.channels.SocketChannel)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 SSLEngine (javax.net.ssl.SSLEngine)1 SSLException (javax.net.ssl.SSLException)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 IgniteClientDisconnectedException (org.apache.ignite.IgniteClientDisconnectedException)1 IgniteException (org.apache.ignite.IgniteException)1