Improved connecting to the network

This commit is contained in:
Christian Basler 2016-08-29 12:30:26 +02:00
parent 53aa2c6804
commit 827973f642

View File

@ -45,8 +45,7 @@ import static ch.dissem.bitmessage.networking.AbstractConnection.State.DISCONNEC
import static ch.dissem.bitmessage.utils.Collections.selectRandom; import static ch.dissem.bitmessage.utils.Collections.selectRandom;
import static ch.dissem.bitmessage.utils.DebugUtils.inc; import static ch.dissem.bitmessage.utils.DebugUtils.inc;
import static ch.dissem.bitmessage.utils.ThreadFactoryBuilder.pool; import static ch.dissem.bitmessage.utils.ThreadFactoryBuilder.pool;
import static java.nio.channels.SelectionKey.OP_READ; import static java.nio.channels.SelectionKey.*;
import static java.nio.channels.SelectionKey.OP_WRITE;
/** /**
* Network handler using java.nio, resulting in less threads. * Network handler using java.nio, resulting in less threads.
@ -203,18 +202,6 @@ public class NioNetworkHandler implements NetworkHandler, InternalContext.Contex
SocketChannel channel = SocketChannel.open(); SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false); channel.configureBlocking(false);
channel.connect(new InetSocketAddress(address.toInetAddress(), address.getPort())); channel.connect(new InetSocketAddress(address.toInetAddress(), address.getPort()));
long timeout = System.currentTimeMillis() + 20_000;
while (!channel.finishConnect() && System.currentTimeMillis() < timeout) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
if (!channel.finishConnect()) {
channel.close();
continue;
}
ConnectionInfo connection = new ConnectionInfo(ctx, CLIENT, ConnectionInfo connection = new ConnectionInfo(ctx, CLIENT,
address, address,
listener, listener,
@ -222,9 +209,18 @@ public class NioNetworkHandler implements NetworkHandler, InternalContext.Contex
); );
connections.put( connections.put(
connection, connection,
channel.register(selector, OP_READ | OP_WRITE, connection) channel.register(selector, OP_CONNECT, connection)
); );
} catch (NoRouteToHostException | AsynchronousCloseException ignore) { } catch (NoRouteToHostException ignore) {
// We'll try to connect to many offline nodes, so
// this is expected to happen quite a lot.
} catch (AsynchronousCloseException e) {
// The exception is expected if the network is being
// shut down, as we actually do asynchronously close
// the connections.
if (isRunning()) {
LOG.error(e.getMessage(), e);
}
} catch (IOException e) { } catch (IOException e) {
LOG.error(e.getMessage(), e); LOG.error(e.getMessage(), e);
} }
@ -268,6 +264,11 @@ public class NioNetworkHandler implements NetworkHandler, InternalContext.Contex
SocketChannel channel = (SocketChannel) key.channel(); SocketChannel channel = (SocketChannel) key.channel();
ConnectionInfo connection = (ConnectionInfo) key.attachment(); ConnectionInfo connection = (ConnectionInfo) key.attachment();
try { try {
if (key.isConnectable()) {
if (!channel.finishConnect()) {
continue;
}
}
if (key.isWritable()) { if (key.isWritable()) {
write(channel, connection); write(channel, connection);
} }
@ -288,13 +289,14 @@ public class NioNetworkHandler implements NetworkHandler, InternalContext.Contex
} }
} }
for (Map.Entry<ConnectionInfo, SelectionKey> e : connections.entrySet()) { for (Map.Entry<ConnectionInfo, SelectionKey> e : connections.entrySet()) {
if (e.getValue().isValid() && (e.getValue().interestOps() & OP_WRITE) == 0) { if (e.getValue().isValid()
if (!e.getKey().getSendingQueue().isEmpty()) { && (e.getValue().interestOps() & OP_WRITE) == 0
&& (e.getValue().interestOps() & OP_CONNECT) == 0
&& !e.getKey().getSendingQueue().isEmpty()) {
e.getValue().interestOps(OP_READ | OP_WRITE); e.getValue().interestOps(OP_READ | OP_WRITE);
} }
} }
} }
}
selector.close(); selector.close();
} catch (ClosedSelectorException ignore) { } catch (ClosedSelectorException ignore) {
} catch (IOException e) { } catch (IOException e) {