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);
}
}
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);
}
}
}
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);
}
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();
}
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;
}
Aggregations