Search in sources :

Example 1 with GridCommunicationClient

use of org.apache.ignite.internal.util.nio.GridCommunicationClient 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 GridCommunicationClient

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

the class TcpCommunicationSpi method safeHandshake.

/**
     * Performs handshake in timeout-safe way.
     *
     * @param client Client.
     * @param recovery Recovery descriptor if use recovery handshake, otherwise {@code null}.
     * @param rmtNodeId Remote node.
     * @param timeout Timeout for handshake.
     * @param sslMeta Session meta.
     * @param handshakeConnIdx Non null connection index if need send it in handshake.
     * @throws IgniteCheckedException If handshake failed or wasn't completed withing timeout.
     * @return Handshake response.
     */
@SuppressWarnings("ThrowFromFinallyBlock")
private <T> long safeHandshake(T client, @Nullable GridNioRecoveryDescriptor recovery, UUID rmtNodeId, long timeout, GridSslMeta sslMeta, @Nullable Integer handshakeConnIdx) throws IgniteCheckedException {
    HandshakeTimeoutObject<T> obj = new HandshakeTimeoutObject<>(client, U.currentTimeMillis() + timeout);
    addTimeoutObject(obj);
    long rcvCnt = 0;
    try {
        if (client instanceof GridCommunicationClient)
            ((GridCommunicationClient) client).doHandshake(new HandshakeClosure(rmtNodeId));
        else {
            SocketChannel ch = (SocketChannel) client;
            boolean success = false;
            try {
                BlockingSslHandler sslHnd = null;
                ByteBuffer buf;
                if (isSslEnabled()) {
                    assert sslMeta != null;
                    sslHnd = new BlockingSslHandler(sslMeta.sslEngine(), ch, directBuf, ByteOrder.nativeOrder(), log);
                    if (!sslHnd.handshake())
                        throw new IgniteCheckedException("SSL handshake is not completed.");
                    ByteBuffer handBuff = sslHnd.applicationBuffer();
                    if (handBuff.remaining() < NodeIdMessage.MESSAGE_FULL_SIZE) {
                        buf = ByteBuffer.allocate(1000);
                        int read = ch.read(buf);
                        if (read == -1)
                            throw new IgniteCheckedException("Failed to read remote node ID (connection closed).");
                        buf.flip();
                        buf = sslHnd.decode(buf);
                    } else
                        buf = handBuff;
                } else {
                    buf = ByteBuffer.allocate(NodeIdMessage.MESSAGE_FULL_SIZE);
                    for (int i = 0; i < NodeIdMessage.MESSAGE_FULL_SIZE; ) {
                        int read = ch.read(buf);
                        if (read == -1)
                            throw new IgniteCheckedException("Failed to read remote node ID (connection closed).");
                        i += read;
                    }
                }
                UUID rmtNodeId0 = U.bytesToUuid(buf.array(), Message.DIRECT_TYPE_SIZE);
                if (!rmtNodeId.equals(rmtNodeId0))
                    throw new IgniteCheckedException("Remote node ID is not as expected [expected=" + rmtNodeId + ", rcvd=" + rmtNodeId0 + ']');
                else if (log.isDebugEnabled())
                    log.debug("Received remote node ID: " + rmtNodeId0);
                if (isSslEnabled()) {
                    assert sslHnd != null;
                    ch.write(sslHnd.encrypt(ByteBuffer.wrap(U.IGNITE_HEADER)));
                } else
                    ch.write(ByteBuffer.wrap(U.IGNITE_HEADER));
                ClusterNode locNode = getLocalNode();
                if (locNode == null)
                    throw new IgniteCheckedException("Local node has not been started or " + "fully initialized [isStopping=" + getSpiContext().isStopping() + ']');
                if (recovery != null) {
                    HandshakeMessage msg;
                    int msgSize = HandshakeMessage.MESSAGE_FULL_SIZE;
                    if (handshakeConnIdx != null) {
                        msg = new HandshakeMessage2(locNode.id(), recovery.incrementConnectCount(), recovery.received(), handshakeConnIdx);
                        msgSize += 4;
                    } else {
                        msg = new HandshakeMessage(locNode.id(), recovery.incrementConnectCount(), recovery.received());
                    }
                    if (log.isDebugEnabled())
                        log.debug("Writing handshake message [locNodeId=" + locNode.id() + ", rmtNode=" + rmtNodeId + ", msg=" + msg + ']');
                    buf = ByteBuffer.allocate(msgSize);
                    buf.order(ByteOrder.nativeOrder());
                    boolean written = msg.writeTo(buf, null);
                    assert written;
                    buf.flip();
                    if (isSslEnabled()) {
                        assert sslHnd != null;
                        ch.write(sslHnd.encrypt(buf));
                    } else
                        ch.write(buf);
                } else {
                    if (isSslEnabled()) {
                        assert sslHnd != null;
                        ch.write(sslHnd.encrypt(ByteBuffer.wrap(nodeIdMessage().nodeIdBytesWithType)));
                    } else
                        ch.write(ByteBuffer.wrap(nodeIdMessage().nodeIdBytesWithType));
                }
                if (recovery != null) {
                    if (log.isDebugEnabled())
                        log.debug("Waiting for handshake [rmtNode=" + rmtNodeId + ']');
                    if (isSslEnabled()) {
                        assert sslHnd != null;
                        buf = ByteBuffer.allocate(1000);
                        buf.order(ByteOrder.nativeOrder());
                        ByteBuffer decode = ByteBuffer.allocate(2 * buf.capacity());
                        decode.order(ByteOrder.nativeOrder());
                        for (int i = 0; i < RecoveryLastReceivedMessage.MESSAGE_FULL_SIZE; ) {
                            int read = ch.read(buf);
                            if (read == -1)
                                throw new IgniteCheckedException("Failed to read remote node recovery handshake " + "(connection closed).");
                            buf.flip();
                            ByteBuffer decode0 = sslHnd.decode(buf);
                            i += decode0.remaining();
                            decode = appendAndResizeIfNeeded(decode, decode0);
                            buf.clear();
                        }
                        decode.flip();
                        rcvCnt = decode.getLong(Message.DIRECT_TYPE_SIZE);
                        if (decode.limit() > RecoveryLastReceivedMessage.MESSAGE_FULL_SIZE) {
                            decode.position(RecoveryLastReceivedMessage.MESSAGE_FULL_SIZE);
                            sslMeta.decodedBuffer(decode);
                        }
                        ByteBuffer inBuf = sslHnd.inputBuffer();
                        if (inBuf.position() > 0)
                            sslMeta.encodedBuffer(inBuf);
                    } else {
                        buf = ByteBuffer.allocate(RecoveryLastReceivedMessage.MESSAGE_FULL_SIZE);
                        buf.order(ByteOrder.nativeOrder());
                        for (int i = 0; i < RecoveryLastReceivedMessage.MESSAGE_FULL_SIZE; ) {
                            int read = ch.read(buf);
                            if (read == -1)
                                throw new IgniteCheckedException("Failed to read remote node recovery handshake " + "(connection closed).");
                            i += read;
                        }
                        rcvCnt = buf.getLong(Message.DIRECT_TYPE_SIZE);
                    }
                    if (log.isDebugEnabled())
                        log.debug("Received handshake message [rmtNode=" + rmtNodeId + ", rcvCnt=" + rcvCnt + ']');
                    if (rcvCnt == -1) {
                        if (log.isDebugEnabled())
                            log.debug("Connection rejected, will retry client creation [rmtNode=" + rmtNodeId + ']');
                    } else
                        success = true;
                } else
                    success = true;
            } catch (IOException e) {
                if (log.isDebugEnabled())
                    log.debug("Failed to read from channel: " + e);
                throw new IgniteCheckedException("Failed to read from channel.", e);
            } finally {
                if (!success)
                    U.closeQuiet(ch);
            }
        }
    } finally {
        boolean cancelled = obj.cancel();
        if (cancelled)
            removeTimeoutObject(obj);
        // Ignoring whatever happened after timeout - reporting only timeout event.
        if (!cancelled)
            throw new HandshakeTimeoutException("Failed to perform handshake due to timeout (consider increasing " + "'connectionTimeout' configuration property).");
    }
    return rcvCnt;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) SocketChannel(java.nio.channels.SocketChannel) BlockingSslHandler(org.apache.ignite.internal.util.nio.ssl.BlockingSslHandler) IOException(java.io.IOException) GridCommunicationClient(org.apache.ignite.internal.util.nio.GridCommunicationClient) ByteBuffer(java.nio.ByteBuffer) IpcEndpoint(org.apache.ignite.internal.util.ipc.IpcEndpoint) IpcSharedMemoryServerEndpoint(org.apache.ignite.internal.util.ipc.shmem.IpcSharedMemoryServerEndpoint) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) EVT_NODE_LEFT(org.apache.ignite.events.EventType.EVT_NODE_LEFT) LT(org.apache.ignite.internal.util.typedef.internal.LT) UUID(java.util.UUID)

Example 3 with GridCommunicationClient

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

the class TcpCommunicationSpi method dumpStats.

/**
     * Dumps SPI per-connection stats to logs.
     */
public void dumpStats() {
    IgniteLogger log = this.log;
    if (log != null) {
        StringBuilder sb = new StringBuilder("Communication SPI recovery descriptors: ").append(U.nl());
        for (Map.Entry<ConnectionKey, GridNioRecoveryDescriptor> entry : recoveryDescs.entrySet()) {
            GridNioRecoveryDescriptor desc = entry.getValue();
            sb.append("    [key=").append(entry.getKey()).append(", msgsSent=").append(desc.sent()).append(", msgsAckedByRmt=").append(desc.acked()).append(", msgsRcvd=").append(desc.received()).append(", lastAcked=").append(desc.lastAcknowledged()).append(", reserveCnt=").append(desc.reserveCount()).append(", descIdHash=").append(System.identityHashCode(desc)).append(']').append(U.nl());
        }
        for (Map.Entry<ConnectionKey, GridNioRecoveryDescriptor> entry : outRecDescs.entrySet()) {
            GridNioRecoveryDescriptor desc = entry.getValue();
            sb.append("    [key=").append(entry.getKey()).append(", msgsSent=").append(desc.sent()).append(", msgsAckedByRmt=").append(desc.acked()).append(", reserveCnt=").append(desc.reserveCount()).append(", connected=").append(desc.connected()).append(", reserved=").append(desc.reserved()).append(", descIdHash=").append(System.identityHashCode(desc)).append(']').append(U.nl());
        }
        for (Map.Entry<ConnectionKey, GridNioRecoveryDescriptor> entry : inRecDescs.entrySet()) {
            GridNioRecoveryDescriptor desc = entry.getValue();
            sb.append("    [key=").append(entry.getKey()).append(", msgsRcvd=").append(desc.received()).append(", lastAcked=").append(desc.lastAcknowledged()).append(", reserveCnt=").append(desc.reserveCount()).append(", connected=").append(desc.connected()).append(", reserved=").append(desc.reserved()).append(", handshakeIdx=").append(desc.handshakeIndex()).append(", descIdHash=").append(System.identityHashCode(desc)).append(']').append(U.nl());
        }
        sb.append("Communication SPI clients: ").append(U.nl());
        for (Map.Entry<UUID, GridCommunicationClient[]> entry : clients.entrySet()) {
            UUID nodeId = entry.getKey();
            GridCommunicationClient[] clients0 = entry.getValue();
            for (GridCommunicationClient client : clients0) {
                if (client != null) {
                    sb.append("    [node=").append(nodeId).append(", client=").append(client).append(']').append(U.nl());
                }
            }
        }
        U.warn(log, sb.toString());
    }
    GridNioServer<Message> nioSrvr = this.nioSrvr;
    if (nioSrvr != null)
        nioSrvr.dumpStats();
}
Also used : Message(org.apache.ignite.plugin.extensions.communication.Message) GridNioRecoveryDescriptor(org.apache.ignite.internal.util.nio.GridNioRecoveryDescriptor) IgniteLogger(org.apache.ignite.IgniteLogger) UUID(java.util.UUID) GridCommunicationClient(org.apache.ignite.internal.util.nio.GridCommunicationClient) Map(java.util.Map) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 4 with GridCommunicationClient

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

the class TcpCommunicationSpi method createNioClient.

/**
     * @param node Node to create client for.
     * @param connIdx Connection index.
     * @return Client.
     * @throws IgniteCheckedException If failed.
     */
@Nullable
private GridCommunicationClient createNioClient(ClusterNode node, int connIdx) throws IgniteCheckedException {
    assert node != null;
    Integer shmemPort = node.attribute(createSpiAttributeName(ATTR_SHMEM_PORT));
    ClusterNode locNode = getSpiContext().localNode();
    if (locNode == null)
        throw new IgniteCheckedException("Failed to create NIO client (local node is stopping)");
    if (log.isDebugEnabled())
        log.debug("Creating NIO client to node: " + node);
    // then we are likely to run on the same host and shared memory communication could be tried.
    if (shmemPort != null && U.sameMacs(locNode, node)) {
        try {
            GridCommunicationClient client = createShmemClient(node, connIdx, shmemPort);
            if (log.isDebugEnabled())
                log.debug("Shmem client created: " + client);
            return client;
        } catch (IgniteCheckedException e) {
            if (e.hasCause(IpcOutOfSystemResourcesException.class))
                // Has cause or is itself the IpcOutOfSystemResourcesException.
                LT.warn(log, OUT_OF_RESOURCES_TCP_MSG);
            else if (getSpiContext().node(node.id()) != null)
                LT.warn(log, e.getMessage());
            else if (log.isDebugEnabled())
                log.debug("Failed to establish shared memory connection with local node (node has left): " + node.id());
        }
    }
    connectGate.enter();
    try {
        GridCommunicationClient client = createTcpClient(node, connIdx);
        if (log.isDebugEnabled())
            log.debug("TCP client created: " + client);
        return client;
    } finally {
        connectGate.leave();
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IpcOutOfSystemResourcesException(org.apache.ignite.internal.util.ipc.shmem.IpcOutOfSystemResourcesException) GridCommunicationClient(org.apache.ignite.internal.util.nio.GridCommunicationClient) Nullable(org.jetbrains.annotations.Nullable)

Example 5 with GridCommunicationClient

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

the class TcpCommunicationSpi method onClientDisconnected.

/** {@inheritDoc} */
@Override
public void onClientDisconnected(IgniteFuture<?> reconnectFut) {
    connectGate.disconnected(reconnectFut);
    for (GridCommunicationClient[] clients0 : clients.values()) {
        for (GridCommunicationClient client : clients0) {
            if (client != null)
                client.forceClose();
        }
    }
    IgniteClientDisconnectedCheckedException err = new IgniteClientDisconnectedCheckedException(reconnectFut, "Failed to connect client node disconnected.");
    for (GridFutureAdapter<GridCommunicationClient> clientFut : clientFuts.values()) clientFut.onDone(err);
    recoveryDescs.clear();
    inRecDescs.clear();
    outRecDescs.clear();
}
Also used : IgniteClientDisconnectedCheckedException(org.apache.ignite.internal.IgniteClientDisconnectedCheckedException) GridCommunicationClient(org.apache.ignite.internal.util.nio.GridCommunicationClient)

Aggregations

GridCommunicationClient (org.apache.ignite.internal.util.nio.GridCommunicationClient)16 UUID (java.util.UUID)9 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)5 ClusterNode (org.apache.ignite.cluster.ClusterNode)4 IpcEndpoint (org.apache.ignite.internal.util.ipc.IpcEndpoint)4 IpcSharedMemoryServerEndpoint (org.apache.ignite.internal.util.ipc.shmem.IpcSharedMemoryServerEndpoint)4 CommunicationSpi (org.apache.ignite.spi.communication.CommunicationSpi)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 GridTcpNioCommunicationClient (org.apache.ignite.internal.util.nio.GridTcpNioCommunicationClient)3 IgniteSpiException (org.apache.ignite.spi.IgniteSpiException)3 IOException (java.io.IOException)2 SocketChannel (java.nio.channels.SocketChannel)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 IgniteClientDisconnectedCheckedException (org.apache.ignite.internal.IgniteClientDisconnectedCheckedException)2 IpcOutOfSystemResourcesException (org.apache.ignite.internal.util.ipc.shmem.IpcOutOfSystemResourcesException)2 GridNioRecoveryDescriptor (org.apache.ignite.internal.util.nio.GridNioRecoveryDescriptor)2 GridNioSession (org.apache.ignite.internal.util.nio.GridNioSession)2 IgniteSpiOperationTimeoutException (org.apache.ignite.spi.IgniteSpiOperationTimeoutException)2 IgniteSpiOperationTimeoutHelper (org.apache.ignite.spi.IgniteSpiOperationTimeoutHelper)2