private void handleKey(Selector selector, SelectionKey key) throws IOException { if (key.isValid() && key.isAcceptable()) { // Accept a new connection, give it a stream connection as an attachment SocketChannel newChannel = sc.accept(); newChannel.configureBlocking(false); SelectionKey newKey = newChannel.register(selector, SelectionKey.OP_READ); try { ConnectionHandler handler = new ConnectionHandler(connectionFactory, newKey); newKey.attach(handler); handler.connection.connectionOpened(); } catch (IOException e) { // This can happen if ConnectionHandler's call to get a new handler returned null log.error("Error handling new connection", Throwables.getRootCause(e).getMessage()); newKey.channel().close(); } } else { // Got a closing channel or a channel to a client connection ConnectionHandler.handleKey(key); } }
@Override public void closeConnections(int n) { while (n-- > 0) { ConnectionHandler handler; synchronized (connectedHandlers) { handler = connectedHandlers.iterator().next(); } if (handler != null) handler.closeConnection(); // Removes handler from connectedHandlers before returning } }
@Override public void closeConnection() { checkState(!lock.isHeldByCurrentThread()); try { channel.close(); } catch (IOException e) { throw new RuntimeException(e); } connectionClosed(); }
StreamConnection connection = data.connection; SocketChannel sc = (SocketChannel) key.channel(); ConnectionHandler handler = new ConnectionHandler(connection, key, connectedHandlers); try { if (sc.finishConnect()) { } else { log.warn("Failed to connect to {}", sc.socket().getRemoteSocketAddress()); handler.closeConnection(); // Failed to connect for some reason data.future.setException(new ConnectException("Unknown reason")); data.future = null; handler.closeConnection(); data.future.setException(cause); data.future = null; ConnectionHandler.handleKey(key);
setWriteOps(); } catch (IOException e) { lock.unlock(); andUnlock = false; log.warn("Error writing message to connection, closing connection", e); closeConnection(); throw e; } catch (CancelledKeyException e) { andUnlock = false; log.warn("Error writing message to connection, closing connection", e); closeConnection(); throw new IOException(e); } finally {
return; if (!key.isValid()) { handler.closeConnection(); // Key has been cancelled, make sure the socket gets closed return; else if (read == -1) { // Socket was closed key.cancel(); handler.closeConnection(); return; handler.tryWriteBytes(); } catch (Exception e) { handler.closeConnection();
private void tryWriteBytes() throws IOException { lock.lock(); try { // Iterate through the outbound ByteBuff queue, pushing as much as possible into the OS' network buffer. Iterator<ByteBuffer> bytesIterator = bytesToWrite.iterator(); while (bytesIterator.hasNext()) { ByteBuffer buff = bytesIterator.next(); bytesToWriteRemaining -= channel.write(buff); if (!buff.hasRemaining()) bytesIterator.remove(); else { setWriteOps(); break; } } // If we are done writing, clear the OP_WRITE interestOps if (bytesToWrite.isEmpty()) key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); // Don't bother waking up the selector here, since we're just removing an op, not adding } finally { lock.unlock(); } }
ConnectionHandler.handleKey(key); // Close connection if relevant
StreamConnection connection = data.connection; SocketChannel sc = (SocketChannel) key.channel(); ConnectionHandler handler = new ConnectionHandler(connection, key, connectedHandlers); try { if (sc.finishConnect()) { } else { log.warn("Failed to connect to {}", sc.socket().getRemoteSocketAddress()); handler.closeConnection(); // Failed to connect for some reason data.future.setException(new ConnectException("Unknown reason")); data.future = null; handler.closeConnection(); data.future.setException(cause); data.future = null; ConnectionHandler.handleKey(key);
setWriteOps(); } catch (IOException e) { lock.unlock(); andUnlock = false; log.warn("Error writing message to connection, closing connection", e); closeConnection(); throw e; } catch (CancelledKeyException e) { andUnlock = false; log.warn("Error writing message to connection, closing connection", e); closeConnection(); throw new IOException(e); } finally {
return; if (!key.isValid()) { handler.closeConnection(); // Key has been cancelled, make sure the socket gets closed return; else if (read == -1) { // Socket was closed key.cancel(); handler.closeConnection(); return; handler.tryWriteBytes(); } catch (Exception e) { handler.closeConnection();
private void tryWriteBytes() throws IOException { lock.lock(); try { // Iterate through the outbound ByteBuff queue, pushing as much as possible into the OS' network buffer. Iterator<ByteBuffer> bytesIterator = bytesToWrite.iterator(); while (bytesIterator.hasNext()) { ByteBuffer buff = bytesIterator.next(); bytesToWriteRemaining -= channel.write(buff); if (!buff.hasRemaining()) bytesIterator.remove(); else { setWriteOps(); break; } } // If we are done writing, clear the OP_WRITE interestOps if (bytesToWrite.isEmpty()) key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); // Don't bother waking up the selector here, since we're just removing an op, not adding } finally { lock.unlock(); } }
ConnectionHandler.handleKey(key); // Close connection if relevant
StreamConnection connection = data.connection; SocketChannel sc = (SocketChannel) key.channel(); ConnectionHandler handler = new ConnectionHandler(connection, key, connectedHandlers); try { if (sc.finishConnect()) { } else { log.warn("Failed to connect to {}", sc.socket().getRemoteSocketAddress()); handler.closeConnection(); // Failed to connect for some reason data.future.setException(new ConnectException("Unknown reason")); data.future = null; handler.closeConnection(); data.future.setException(cause); data.future = null; ConnectionHandler.handleKey(key);
private void handleKey(Selector selector, SelectionKey key) throws IOException { if (key.isValid() && key.isAcceptable()) { // Accept a new connection, give it a stream connection as an attachment SocketChannel newChannel = sc.accept(); newChannel.configureBlocking(false); SelectionKey newKey = newChannel.register(selector, SelectionKey.OP_READ); try { ConnectionHandler handler = new ConnectionHandler(connectionFactory, newKey); newKey.attach(handler); handler.connection.connectionOpened(); } catch (IOException e) { // This can happen if ConnectionHandler's call to get a new handler returned null log.error("Error handling new connection", Throwables.getRootCause(e).getMessage()); newKey.channel().close(); } } else { // Got a closing channel or a channel to a client connection ConnectionHandler.handleKey(key); } }
setWriteOps(); } catch (IOException e) { lock.unlock(); andUnlock = false; log.warn("Error writing message to connection, closing connection", e); closeConnection(); throw e; } catch (CancelledKeyException e) { andUnlock = false; log.warn("Error writing message to connection, closing connection", e); closeConnection(); throw new IOException(e); } finally {
return; if (!key.isValid()) { handler.closeConnection(); // Key has been cancelled, make sure the socket gets closed return; else if (read == -1) { // Socket was closed key.cancel(); handler.closeConnection(); return; handler.tryWriteBytes(); } catch (Exception e) { handler.closeConnection();
@Override public void closeConnection() { checkState(!lock.isHeldByCurrentThread()); try { channel.close(); } catch (IOException e) { throw new RuntimeException(e); } connectionClosed(); }
@Override public void closeConnections(int n) { while (n-- > 0) { ConnectionHandler handler; synchronized (connectedHandlers) { handler = connectedHandlers.iterator().next(); } if (handler != null) handler.closeConnection(); // Removes handler from connectedHandlers before returning } }
private void tryWriteBytes() throws IOException { lock.lock(); try { // Iterate through the outbound ByteBuff queue, pushing as much as possible into the OS' network buffer. Iterator<ByteBuffer> bytesIterator = bytesToWrite.iterator(); while (bytesIterator.hasNext()) { ByteBuffer buff = bytesIterator.next(); bytesToWriteRemaining -= channel.write(buff); if (!buff.hasRemaining()) bytesIterator.remove(); else { setWriteOps(); break; } } // If we are done writing, clear the OP_WRITE interestOps if (bytesToWrite.isEmpty()) key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); // Don't bother waking up the selector here, since we're just removing an op, not adding } finally { lock.unlock(); } }