Author: toad
Date: 2006-05-31 17:49:26 +0000 (Wed, 31 May 2006)
New Revision: 8957
Modified:
trunk/freenet/src/freenet/io/xfer/BlockTransmitter.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/NodeDispatcher.java
trunk/freenet/src/freenet/node/Version.java
Log:
761 (self-mandatory): Fix major bugs in shouldRejectRequest().
Modified: trunk/freenet/src/freenet/io/xfer/BlockTransmitter.java
===================================================================
--- trunk/freenet/src/freenet/io/xfer/BlockTransmitter.java 2006-05-31
17:03:52 UTC (rev 8956)
+++ trunk/freenet/src/freenet/io/xfer/BlockTransmitter.java 2006-05-31
17:49:26 UTC (rev 8957)
@@ -493,4 +493,43 @@
public PeerContext getDestination() {
return _destination;
}
+
+ public static boolean isUncontended() {
+ long nowNS = System.currentTimeMillis() * 1000 * 1000;
+
+ // Synchronize on the static lock, and update
+ synchronized(lastPacketSendTimeSync) {
+
+ // Get the current time
+ nowNS = System.currentTimeMillis() * 1000 * 1000;
+
+ // Update time if necessary to avoid spurts
+ if(hardLastPacketSendTimeNSec < (nowNS -
minPacketDelayNSec)) {
+ // Can send immediately!
+ } else {
+ return false; // is contended.
+ }
+
+ // What about the soft limit?
+
+ // We can only accumulate burst traffic rights for a
full period at most.
+ // If we have a period of 1 hour, and we send no
traffic in the first 30 minutes,
+ // then we can use up our whole hour's quota in the
next 30 minutes if we need to.
+ // We could even use our entire quota in the last 5
minutes. After that, we can
+ // only send at the limit (which may be very low),
since we have no quota left.
+ // However, after 1 hour we forget our burst rights.
+ if(nowNS - softLastPacketSendTimeNSec >
softLimitPeriodNSec) {
+ softLastPacketSendTimeNSec = nowNS -
(softLimitPeriodNSec);
+ }
+
+ softLastPacketSendTimeNSec += minSoftDelayNSec;
+
+ if(softLastPacketSendTimeNSec > nowNS) {
+ // Can't send immediately due to soft limit.
+ return false;
+ }
+ }
+
+ return true;
+ }
}
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-05-31 17:03:52 UTC (rev
8956)
+++ trunk/freenet/src/freenet/node/Node.java 2006-05-31 17:49:26 UTC (rev
8957)
@@ -1950,22 +1950,30 @@
long lastAcceptedRequest = -1;
- public synchronized boolean shouldRejectRequest() {
+ long lastCheckedUncontended = -1;
+
+ public synchronized boolean shouldRejectRequest(boolean canAcceptAnyway) {
long now = System.currentTimeMillis();
+ if(lastCheckedUncontended - now > 1000) {
+ lastCheckedUncontended = now;
+ if(BlockTransmitter.isUncontended())
+ throttledPacketSendAverage.report(0);
+ }
+
// Round trip time
double pingTime = nodePinger.averagePingTime();
if(pingTime > MAX_PING_TIME) {
- if(now - lastAcceptedRequest > MAX_INTERREQUEST_TIME) {
+ if(now - lastAcceptedRequest > MAX_INTERREQUEST_TIME &&
canAcceptAnyway) {
Logger.minor(this, "Accepting request anyway (take one
every 10 secs to keep bwlimitDelayTime updated)");
lastAcceptedRequest = now;
return false;
}
- Logger.minor( this, "shouldRejectRequest() == true because
>MAX_PING_TIME");
+ Logger.minor( this, "shouldRejectRequest("+canAcceptAnyway+")
== true because >MAX_PING_TIME");
return true;
}
if(pingTime > SUB_MAX_PING_TIME) {
- double x = (pingTime - SUB_MAX_PING_TIME) / (MAX_PING_TIME -
SUB_MAX_PING_TIME);
+ double x = ((double)(pingTime - SUB_MAX_PING_TIME)) /
(MAX_PING_TIME - SUB_MAX_PING_TIME);
if(random.nextDouble() < x) {
Logger.minor( this, "shouldRejectRequest() == true
because >SUB_MAX_PING_TIME");
return true;
@@ -1977,7 +1985,7 @@
double bwlimitDelayTime =
this.throttledPacketSendAverage.currentValue();
Logger.minor(this, "bwlimitDelayTime = "+bwlimitDelayTime);
if(bwlimitDelayTime > MAX_THROTTLE_DELAY) {
- if(now - lastAcceptedRequest > MAX_INTERREQUEST_TIME) {
+ if(now - lastAcceptedRequest > MAX_INTERREQUEST_TIME &&
canAcceptAnyway) {
Logger.minor(this, "Accepting request anyway (take one
every 10 secs to keep bwlimitDelayTime updated)");
lastAcceptedRequest = now;
return false;
@@ -1986,13 +1994,15 @@
return true;
}
if(bwlimitDelayTime > SUB_MAX_THROTTLE_DELAY) {
- double x = (pingTime - SUB_MAX_THROTTLE_DELAY) /
(MAX_THROTTLE_DELAY - SUB_MAX_THROTTLE_DELAY);
+ double x = ((double)(bwlimitDelayTime -
SUB_MAX_THROTTLE_DELAY)) / (MAX_THROTTLE_DELAY - SUB_MAX_THROTTLE_DELAY);
if(random.nextDouble() < x) {
- Logger.minor( this, "shouldRejectRequest() == true
because >SUB_MAX_THROTTLE_DELAY");
+ Logger.minor( this,
"shouldRejectRequest("+canAcceptAnyway+") == true because
>SUB_MAX_THROTTLE_DELAY");
return true;
}
}
+ Logger.minor(this, "Accepting request");
+
lastAcceptedRequest = now;
return false;
}
Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java 2006-05-31 17:03:52 UTC
(rev 8956)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java 2006-05-31 17:49:26 UTC
(rev 8957)
@@ -71,10 +71,14 @@
return handleRoutedReply(m);
} else if(spec == DMT.FNPRoutedRejected) {
return handleRoutedRejected(m);
- } else if(spec == DMT.FNPCHKDataRequest || spec ==
DMT.FNPSSKDataRequest) {
- return handleDataRequest(m);
- } else if(spec == DMT.FNPInsertRequest || spec ==
DMT.FNPSSKInsertRequest) {
- return handleInsertRequest(m);
+ } else if(spec == DMT.FNPCHKDataRequest) {
+ return handleDataRequest(m, false);
+ } else if(spec == DMT.FNPSSKDataRequest) {
+ return handleDataRequest(m, true);
+ } else if(spec == DMT.FNPInsertRequest) {
+ return handleInsertRequest(m, false);
+ } else if(spec == DMT.FNPSSKInsertRequest) {
+ return handleInsertRequest(m, true);
} else if(spec == DMT.FNPLinkPing) {
long id = m.getLong(DMT.PING_SEQNO);
Message msg = DMT.createFNPLinkPong(id);
@@ -104,7 +108,7 @@
/**
* Handle an incoming FNPDataRequest.
*/
- private boolean handleDataRequest(Message m) {
+ private boolean handleDataRequest(Message m, boolean isSSK) {
long id = m.getLong(DMT.UID);
if(node.recentlyCompleted(id)) {
Message rejected = DMT.createFNPRejectedLoop(id);
@@ -115,7 +119,8 @@
}
return true;
}
- if(node.shouldRejectRequest()) {
+ if(node.shouldRejectRequest(!isSSK)) {
+ // can accept 1 CHK request every so often, but not with SSKs
because they aren't throttled so won't sort out bwlimitDelayTime, which was the
whole reason for accepting them when overloaded...
Logger.normal(this, "Rejecting request from
"+m.getSource().getPeer()+" preemptively");
Message rejected = DMT.createFNPRejectedOverload(id, true);
try {
@@ -146,7 +151,7 @@
return true;
}
- private boolean handleInsertRequest(Message m) {
+ private boolean handleInsertRequest(Message m, boolean isSSK) {
long now = System.currentTimeMillis();
long id = m.getLong(DMT.UID);
if(node.recentlyCompleted(id)) {
@@ -158,7 +163,8 @@
}
return true;
}
- if(node.shouldRejectRequest()) {
+ // SSKs don't fix bwlimitDelayTime so shouldn't be accepted when
overloaded.
+ if(node.shouldRejectRequest(!isSSK)) {
Logger.normal(this, "Rejecting insert from
"+m.getSource().getPeer()+" preemptively");
Message rejected = DMT.createFNPRejectedOverload(id, true);
try {
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-05-31 17:03:52 UTC (rev
8956)
+++ trunk/freenet/src/freenet/node/Version.java 2006-05-31 17:49:26 UTC (rev
8957)
@@ -18,10 +18,10 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 760;
+ private static final int buildNumber = 761;
/** Oldest build of Fred we will talk to */
- private static final int lastGoodBuild = 759;
+ private static final int lastGoodBuild = 761;
public static final int buildNumber() {
return buildNumber;