Search in sources :

Example 1 with SelectionKey

use of java.nio.channels.SelectionKey in project kafka by apache.

the class Selector method connect.

/**
     * Begin connecting to the given address and add the connection to this nioSelector associated with the given id
     * number.
     * <p>
     * Note that this call only initiates the connection, which will be completed on a future {@link #poll(long)}
     * call. Check {@link #connected()} to see which (if any) connections have completed after a given poll call.
     * @param id The id for the new connection
     * @param address The address to connect to
     * @param sendBufferSize The send buffer for the new connection
     * @param receiveBufferSize The receive buffer for the new connection
     * @throws IllegalStateException if there is already a connection for that id
     * @throws IOException if DNS resolution fails on the hostname or if the broker is down
     */
@Override
public void connect(String id, InetSocketAddress address, int sendBufferSize, int receiveBufferSize) throws IOException {
    if (this.channels.containsKey(id))
        throw new IllegalStateException("There is already a connection for id " + id);
    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.configureBlocking(false);
    Socket socket = socketChannel.socket();
    socket.setKeepAlive(true);
    if (sendBufferSize != Selectable.USE_DEFAULT_BUFFER_SIZE)
        socket.setSendBufferSize(sendBufferSize);
    if (receiveBufferSize != Selectable.USE_DEFAULT_BUFFER_SIZE)
        socket.setReceiveBufferSize(receiveBufferSize);
    socket.setTcpNoDelay(true);
    boolean connected;
    try {
        connected = socketChannel.connect(address);
    } catch (UnresolvedAddressException e) {
        socketChannel.close();
        throw new IOException("Can't resolve address: " + address, e);
    } catch (IOException e) {
        socketChannel.close();
        throw e;
    }
    SelectionKey key = socketChannel.register(nioSelector, SelectionKey.OP_CONNECT);
    KafkaChannel channel = channelBuilder.buildChannel(id, key, maxReceiveSize);
    key.attach(channel);
    this.channels.put(id, channel);
    if (connected) {
        // OP_CONNECT won't trigger for immediately connected channels
        log.debug("Immediately connected to node {}", channel.id());
        immediatelyConnectedKeys.add(key);
        key.interestOps(0);
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) SelectionKey(java.nio.channels.SelectionKey) UnresolvedAddressException(java.nio.channels.UnresolvedAddressException) IOException(java.io.IOException) Socket(java.net.Socket)

Example 2 with SelectionKey

use of java.nio.channels.SelectionKey in project kafka by apache.

the class Selector method pollSelectionKeys.

private void pollSelectionKeys(Iterable<SelectionKey> selectionKeys, boolean isImmediatelyConnected, long currentTimeNanos) {
    Iterator<SelectionKey> iterator = selectionKeys.iterator();
    while (iterator.hasNext()) {
        SelectionKey key = iterator.next();
        iterator.remove();
        KafkaChannel channel = channel(key);
        // register all per-connection metrics at once
        sensors.maybeRegisterConnectionMetrics(channel.id());
        if (idleExpiryManager != null)
            idleExpiryManager.update(channel.id(), currentTimeNanos);
        try {
            /* complete any connections that have finished their handshake (either normally or immediately) */
            if (isImmediatelyConnected || key.isConnectable()) {
                if (channel.finishConnect()) {
                    this.connected.add(channel.id());
                    this.sensors.connectionCreated.record();
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    log.debug("Created socket with SO_RCVBUF = {}, SO_SNDBUF = {}, SO_TIMEOUT = {} to node {}", socketChannel.socket().getReceiveBufferSize(), socketChannel.socket().getSendBufferSize(), socketChannel.socket().getSoTimeout(), channel.id());
                } else
                    continue;
            }
            /* if channel is not ready finish prepare */
            if (channel.isConnected() && !channel.ready())
                channel.prepare();
            /* if channel is ready read from any connections that have readable data */
            if (channel.ready() && key.isReadable() && !hasStagedReceive(channel)) {
                NetworkReceive networkReceive;
                while ((networkReceive = channel.read()) != null) addToStagedReceives(channel, networkReceive);
            }
            /* if channel is ready write to any sockets that have space in their buffer and for which we have data */
            if (channel.ready() && key.isWritable()) {
                Send send = channel.write();
                if (send != null) {
                    this.completedSends.add(send);
                    this.sensors.recordBytesSent(channel.id(), send.size());
                }
            }
            /* cancel any defunct sockets */
            if (!key.isValid())
                close(channel, true);
        } catch (Exception e) {
            String desc = channel.socketDescription();
            if (e instanceof IOException)
                log.debug("Connection with {} disconnected", desc, e);
            else
                log.warn("Unexpected error from {}; closing connection", desc, e);
            close(channel, true);
        }
    }
}
Also used : SelectionKey(java.nio.channels.SelectionKey) SocketChannel(java.nio.channels.SocketChannel) IOException(java.io.IOException) CancelledKeyException(java.nio.channels.CancelledKeyException) KafkaException(org.apache.kafka.common.KafkaException) ClosedChannelException(java.nio.channels.ClosedChannelException) IOException(java.io.IOException) UnresolvedAddressException(java.nio.channels.UnresolvedAddressException)

Example 3 with SelectionKey

use of java.nio.channels.SelectionKey in project kafka by apache.

the class Selector method register.

/**
     * Register the nioSelector with an existing channel
     * Use this on server-side, when a connection is accepted by a different thread but processed by the Selector
     * Note that we are not checking if the connection id is valid - since the connection already exists
     */
public void register(String id, SocketChannel socketChannel) throws ClosedChannelException {
    SelectionKey key = socketChannel.register(nioSelector, SelectionKey.OP_READ);
    KafkaChannel channel = channelBuilder.buildChannel(id, key, maxReceiveSize);
    key.attach(channel);
    this.channels.put(id, channel);
}
Also used : SelectionKey(java.nio.channels.SelectionKey)

Example 4 with SelectionKey

use of java.nio.channels.SelectionKey in project tomcat by apache.

the class NioReceiver method socketTimeouts.

protected void socketTimeouts() {
    long now = System.currentTimeMillis();
    if ((now - lastCheck) < getSelectorTimeout())
        return;
    //timeout
    Selector tmpsel = this.selector.get();
    Set<SelectionKey> keys = (isListening() && tmpsel != null) ? tmpsel.keys() : null;
    if (keys == null)
        return;
    for (Iterator<SelectionKey> iter = keys.iterator(); iter.hasNext(); ) {
        SelectionKey key = iter.next();
        try {
            //                else
            if (key.interestOps() == 0) {
                //check for keys that didn't make it in.
                ObjectReader ka = (ObjectReader) key.attachment();
                if (ka != null) {
                    long delta = now - ka.getLastAccess();
                    if (delta > getTimeout() && (!ka.isAccessed())) {
                        if (log.isWarnEnabled())
                            log.warn(sm.getString("nioReceiver.threadsExhausted", Integer.valueOf(getTimeout()), Boolean.valueOf(ka.isCancelled()), key, new java.sql.Timestamp(ka.getLastAccess())));
                        ka.setLastAccess(now);
                    //key.interestOps(SelectionKey.OP_READ);
                    }
                //end if
                } else {
                    cancelledKey(key);
                }
            //end if
            }
        //end if
        } catch (CancelledKeyException ckx) {
            cancelledKey(key);
        }
    }
    lastCheck = System.currentTimeMillis();
}
Also used : SelectionKey(java.nio.channels.SelectionKey) CancelledKeyException(java.nio.channels.CancelledKeyException) ObjectReader(org.apache.catalina.tribes.io.ObjectReader) Selector(java.nio.channels.Selector)

Example 5 with SelectionKey

use of java.nio.channels.SelectionKey in project tomcat by apache.

the class ParallelNioSender method doLoop.

private int doLoop(long selectTimeOut, int maxAttempts, boolean waitForAck, ChannelMessage msg) throws IOException, ChannelException {
    int completed = 0;
    int selectedKeys = selector.select(selectTimeOut);
    if (selectedKeys == 0) {
        return 0;
    }
    Iterator<SelectionKey> it = selector.selectedKeys().iterator();
    while (it.hasNext()) {
        SelectionKey sk = it.next();
        it.remove();
        int readyOps = sk.readyOps();
        sk.interestOps(sk.interestOps() & ~readyOps);
        NioSender sender = (NioSender) sk.attachment();
        try {
            if (sender.process(sk, waitForAck)) {
                completed++;
                sender.setComplete(true);
                if (Logs.MESSAGES.isTraceEnabled()) {
                    Logs.MESSAGES.trace("ParallelNioSender - Sent msg:" + new UniqueId(msg.getUniqueId()) + " at " + new java.sql.Timestamp(System.currentTimeMillis()) + " to " + sender.getDestination().getName());
                }
                SenderState.getSenderState(sender.getDestination()).setReady();
            }
        //end if
        } catch (Exception x) {
            if (log.isTraceEnabled()) {
                log.trace("Error while processing send to " + sender.getDestination().getName(), x);
            }
            SenderState state = SenderState.getSenderState(sender.getDestination());
            int attempt = sender.getAttempt() + 1;
            boolean retry = (sender.getAttempt() <= maxAttempts && maxAttempts > 0);
            synchronized (state) {
                //sk.cancel();
                if (state.isSuspect())
                    state.setFailing();
                if (state.isReady()) {
                    state.setSuspect();
                    if (retry)
                        log.warn(sm.getString("parallelNioSender.send.fail.retrying", sender.getDestination().getName()));
                    else
                        log.warn(sm.getString("parallelNioSender.send.fail", sender.getDestination().getName()), x);
                }
            }
            if (!isConnected()) {
                log.warn(sm.getString("parallelNioSender.sender.disconnected.notRetry", sender.getDestination().getName()));
                ChannelException cx = new ChannelException(sm.getString("parallelNioSender.sender.disconnected.sendFailed"), x);
                cx.addFaultyMember(sender.getDestination(), x);
                throw cx;
            }
            byte[] data = sender.getMessage();
            if (retry) {
                try {
                    sender.disconnect();
                    sender.connect();
                    sender.setAttempt(attempt);
                    sender.setMessage(data);
                } catch (Exception ignore) {
                    state.setFailing();
                }
            } else {
                ChannelException cx = new ChannelException(sm.getString("parallelNioSender.sendFailed.attempt", Integer.toString(sender.getAttempt()), Integer.toString(maxAttempts)), x);
                cx.addFaultyMember(sender.getDestination(), x);
                throw cx;
            }
        //end if
        }
    }
    return completed;
}
Also used : SelectionKey(java.nio.channels.SelectionKey) UniqueId(org.apache.catalina.tribes.UniqueId) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) ChannelException(org.apache.catalina.tribes.ChannelException) SenderState(org.apache.catalina.tribes.transport.SenderState) ChannelException(org.apache.catalina.tribes.ChannelException)

Aggregations

SelectionKey (java.nio.channels.SelectionKey)190 IOException (java.io.IOException)87 SocketChannel (java.nio.channels.SocketChannel)56 Selector (java.nio.channels.Selector)42 ServerSocketChannel (java.nio.channels.ServerSocketChannel)39 ClosedChannelException (java.nio.channels.ClosedChannelException)30 InetSocketAddress (java.net.InetSocketAddress)26 CancelledKeyException (java.nio.channels.CancelledKeyException)25 ByteBuffer (java.nio.ByteBuffer)23 ClosedSelectorException (java.nio.channels.ClosedSelectorException)17 SelectableChannel (java.nio.channels.SelectableChannel)13 Test (org.junit.Test)13 Iterator (java.util.Iterator)9 Socket (java.net.Socket)7 ArrayList (java.util.ArrayList)7 SocketTimeoutException (java.net.SocketTimeoutException)6 AbstractSelectionKey (java.nio.channels.spi.AbstractSelectionKey)6 EOFException (java.io.EOFException)5 DatagramChannel (java.nio.channels.DatagramChannel)5 HashSet (java.util.HashSet)5