Improved connection management, preventing multiple connections to the same node, and improved broadcast handling.

This commit is contained in:
2015-06-12 06:57:20 +02:00
parent fe93c95f40
commit bd5bf76904
9 changed files with 172 additions and 20 deletions

View File

@ -29,10 +29,13 @@ import ch.dissem.bitmessage.utils.Security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
@ -161,7 +164,7 @@ public class Connection implements Runnable {
listener.receive(objectMessage);
ctx.getInventory().storeObject(objectMessage);
} catch (InsufficientProofOfWorkException e) {
// DebugUtils.saveToFile(objectMessage);
LOG.warn(e.getMessage());
} catch (IOException e) {
LOG.error("Stream " + objectMessage.getStream() + ", object type " + objectMessage.getType() + ": " + e.getMessage(), e);
DebugUtils.saveToFile(objectMessage);
@ -217,5 +220,18 @@ public class Connection implements Runnable {
.build());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Connection that = (Connection) o;
return Objects.equals(node, that.node);
}
@Override
public int hashCode() {
return Objects.hash(node);
}
public enum State {SERVER, CLIENT, ACTIVE, DISCONNECTED}
}

View File

@ -21,6 +21,7 @@ import ch.dissem.bitmessage.InternalContext.ContextHolder;
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress;
import ch.dissem.bitmessage.ports.NetworkHandler;
import ch.dissem.bitmessage.utils.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -87,8 +88,8 @@ public class NetworkNode implements NetworkHandler, ContextHolder {
}
}
}
if (connections.size() < 1) {
List<NetworkAddress> addresses = ctx.getNodeRegistry().getKnownAddresses(8, ctx.getStreams());
if (connections.size() < 8) {
List<NetworkAddress> addresses = ctx.getNodeRegistry().getKnownAddresses(8 - connections.size(), ctx.getStreams());
for (NetworkAddress address : addresses) {
try {
startConnection(new Connection(ctx, CLIENT, new Socket(address.toInetAddress(), address.getPort()), listener));
@ -96,7 +97,6 @@ public class NetworkNode implements NetworkHandler, ContextHolder {
LOG.debug(e.getMessage(), e);
}
}
// FIXME: prevent connecting twice to the same node
}
try {
Thread.sleep(30000);
@ -131,6 +131,10 @@ public class NetworkNode implements NetworkHandler, ContextHolder {
private void startConnection(Connection c) {
synchronized (connections) {
// prevent connecting twice to the same node
if (connections.contains(c)) {
return;
}
connections.add(c);
}
pool.execute(c);
@ -138,12 +142,10 @@ public class NetworkNode implements NetworkHandler, ContextHolder {
@Override
public void offer(final InventoryVector iv) {
// TODO:
// - should offer to (random) 8 nodes during 8 seconds (if possible)
// - should probably offer later if no connection available at the moment?
synchronized (connections) {
LOG.debug(connections.size() + " connections available to offer " + iv);
for (Connection connection : connections) {
List<Connection> random8 = Collections.selectRandom(8, this.connections);
for (Connection connection : random8) {
connection.offer(iv);
}
}