Cleaning up requested objects from time to time, to work around a leak that sometimes happens.

This commit is contained in:
Christian Basler 2016-09-21 19:37:17 +02:00
parent 7e201dd2cf
commit a18f76f864

View File

@ -53,6 +53,7 @@ import static java.util.Collections.newSetFromMap;
*/ */
public class NioNetworkHandler implements NetworkHandler, InternalContext.ContextHolder { public class NioNetworkHandler implements NetworkHandler, InternalContext.ContextHolder {
private static final Logger LOG = LoggerFactory.getLogger(NioNetworkHandler.class); private static final Logger LOG = LoggerFactory.getLogger(NioNetworkHandler.class);
private static final long REQUESTED_OBJECTS_MAX_TIME = 30 * 60_000; // 30 minutes
private final ExecutorService threadPool = Executors.newCachedThreadPool( private final ExecutorService threadPool = Executors.newCachedThreadPool(
pool("network") pool("network")
@ -66,6 +67,7 @@ public class NioNetworkHandler implements NetworkHandler, InternalContext.Contex
private Queue<NetworkAddress> connectionQueue = new ConcurrentLinkedQueue<>(); private Queue<NetworkAddress> connectionQueue = new ConcurrentLinkedQueue<>();
private Map<ConnectionInfo, SelectionKey> connections = new ConcurrentHashMap<>(); private Map<ConnectionInfo, SelectionKey> connections = new ConcurrentHashMap<>();
private final Set<InventoryVector> requestedObjects = newSetFromMap(new ConcurrentHashMap<InventoryVector, Boolean>(10_000)); private final Set<InventoryVector> requestedObjects = newSetFromMap(new ConcurrentHashMap<InventoryVector, Boolean>(10_000));
private long requestedObjectsTimeout = 0;
private Thread starter; private Thread starter;
@ -145,6 +147,8 @@ public class NioNetworkHandler implements NetworkHandler, InternalContext.Contex
} catch (IOException e) { } catch (IOException e) {
throw new ApplicationException(e); throw new ApplicationException(e);
} }
requestedObjectsTimeout = System.currentTimeMillis() + REQUESTED_OBJECTS_MAX_TIME;
requestedObjects.clear();
starter = thread("connection manager", new Runnable() { starter = thread("connection manager", new Runnable() {
@Override @Override
@ -181,6 +185,20 @@ public class NioNetworkHandler implements NetworkHandler, InternalContext.Contex
it.remove(); it.remove();
} }
} }
// The list 'requested objects' helps to prevent downloading an object
// twice. From time to time there is an error though, and an object is
// never downloaded. To prevent a large list of failed objects and give
// them a chance to get downloaded again, let's clear the list from time
// to time. The timeout should be such that most of the initial object
// sync should be done by then, but small enough to prevent objects with
// a normal time out from not being downloaded at all.
long now = System.currentTimeMillis();
if (now > requestedObjectsTimeout) {
requestedObjectsTimeout = now + REQUESTED_OBJECTS_MAX_TIME;
requestedObjects.clear();
}
try { try {
Thread.sleep(30_000); Thread.sleep(30_000);
} catch (InterruptedException e) { } catch (InterruptedException e) {