diff --git a/history.txt b/history.txt index 67499a57ec..02f38d7661 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,8 @@ -$Id: history.txt,v 1.402 2006/02/16 15:44:07 jrandom Exp $ +$Id: history.txt,v 1.403 2006/02/17 04:07:53 jrandom Exp $ + +2006-02-17 jrandom + * Properly fix the build request queue throttling, using queue age to + detect congestion, rather than queue size. 2006-02-17 jrandom * Disable the message history log file by default (duh - feel free to diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 594dc0d8eb..376e901a66 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -15,9 +15,9 @@ import net.i2p.CoreVersion; * */ public class RouterVersion { - public final static String ID = "$Revision: 1.345 $ $Date: 2006/02/16 15:44:12 $"; + public final static String ID = "$Revision: 1.346 $ $Date: 2006/02/17 04:07:53 $"; public final static String VERSION = "0.6.1.10"; - public final static long BUILD = 1; + public final static long BUILD = 2; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID); diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java index e3a62b2cb5..80e67e824c 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java @@ -117,9 +117,11 @@ class BuildExecutor implements Runnable { List wanted = new ArrayList(8); List pools = new ArrayList(8); + boolean pendingRemaining = false; + while (!_manager.isShutdown()){ try { - _repoll = false; + _repoll = pendingRemaining; // resets repoll to false unless there are inbound requeusts pending _manager.listPools(pools); for (int i = 0; i < pools.size(); i++) { TunnelPool pool = (TunnelPool)pools.get(i); @@ -199,9 +201,7 @@ class BuildExecutor implements Runnable { } } - boolean pendingRemaining = _handler.handleInboundRequests(); - if (pendingRemaining) - _repoll = true; + pendingRemaining = _handler.handleInboundRequests(); wanted.clear(); pools.clear(); diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index 5515e5d156..a10405bc49 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -43,6 +43,8 @@ class BuildHandler { _context.statManager().createRateStat("tunnel.rejectOverloaded", "How long we had to wait before processing the request (when it was rejected)", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.acceptLoad", "How long we had to wait before processing the request (when it was accepted)", "Tunnels", new long[] { 60*1000, 10*60*1000 }); + _context.statManager().createRateStat("tunnel.dropLoad", "How long we had to wait before finally giving up on an inbound request (period is queue count)?", "Tunnels", new long[] { 60*1000, 10*60*1000 }); + _context.statManager().createRateStat("tunnel.handleRemaining", "How many pending inbound requests were left on the queue after one pass?", "Tunnels", new long[] { 60*1000, 10*60*1000 }); _context.statManager().createRateStat("tunnel.receiveRejectionProbabalistic", "How often we are rejected probabalistically?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l }); _context.statManager().createRateStat("tunnel.receiveRejectionTransient", "How often we are rejected due to transient overload?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l }); @@ -57,10 +59,6 @@ class BuildHandler { } private static final int MAX_HANDLE_AT_ONCE = 5; - /** - * Don't keep too many messages on the queue - when it reaches this size, delete the oldest request - */ - private static final int MAX_QUEUED_REQUESTS = MAX_HANDLE_AT_ONCE * (BuildRequestor.REQUEST_TIMEOUT/1000); private static final int NEXT_HOP_LOOKUP_TIMEOUT = 5*1000; /** @@ -112,7 +110,10 @@ class BuildHandler { // anything else? synchronized (_inboundBuildMessages) { - return _inboundBuildMessages.size() > 0; + int remaining = _inboundBuildMessages.size(); + if (remaining > 0) + _context.statManager().addRateData("tunnel.handleRemaining", remaining, 0); + return remaining > 0; } } @@ -516,8 +517,17 @@ class BuildHandler { _log.warn("Dropping the reply " + reqId + ", as we used to be building that"); } else { synchronized (_inboundBuildMessages) { - while (_inboundBuildMessages.size() > MAX_QUEUED_REQUESTS) - _inboundBuildMessages.remove(0); // keep the newest requests first, to offer better service + boolean removed = false; + while (_inboundBuildMessages.size() > 0) { + BuildMessageState cur = (BuildMessageState)_inboundBuildMessages.get(0); + long age = System.currentTimeMillis() - cur.recvTime; + if (age >= BuildRequestor.REQUEST_TIMEOUT) { + _inboundBuildMessages.remove(0); + _context.statManager().addRateData("tunnel.dropLoad", age, _inboundBuildMessages.size()); + } else { + break; + } + } _inboundBuildMessages.add(new BuildMessageState(receivedMessage, from, fromHash)); } _exec.repoll();