Update of /cvsroot/freenet/freenet/src/freenet/node/rt
In directory sc8-pr-cvs1:/tmp/cvs-serv13668/src/freenet/node/rt
Modified Files:
NGRouting.java NGRoutingTable.java StandardNodeEstimator.java
NodeEstimator.java StandardNodeEstimatorFactory.java
Log Message:
6333: Implement exponential backoff.
Index: NGRouting.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/NGRouting.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -w -r1.27 -r1.28
--- NGRouting.java 13 Nov 2003 16:18:55 -0000 1.27
+++ NGRouting.java 13 Nov 2003 20:49:54 -0000 1.28
@@ -73,7 +73,8 @@
count++;
lastTime = System.currentTimeMillis();
NodeReference ref = last.reference();
- if(desperate || freeConn(ref.getIdentity())) {
+ if((desperate || freeConn(ref.getIdentity())) &&
+ (!last.isBackedOff())) {
hasSearchFailed = false;
lastTime = System.currentTimeMillis();
logDEBUG = Core.logger.shouldLog(Logger.DEBUG,this);
Index: NGRoutingTable.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/NGRoutingTable.java,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -w -r1.39 -r1.40
--- NGRoutingTable.java 13 Nov 2003 02:16:58 -0000 1.39
+++ NGRoutingTable.java 13 Nov 2003 20:49:54 -0000 1.40
@@ -377,10 +377,12 @@
int triedNodes = 0;
long totalConnectAttempts = 0;
long totalConnectSuccesses = 0;
+ int backedOffNodes = 0;
synchronized(this) {
Enumeration elements = estimators.elements();
while(elements.hasMoreElements()) {
NodeEstimator e =
(NodeEstimator)(elements.nextElement());
+ if(e.isBackedOff()) backedOffNodes++;
NodeReference ref = e.reference();
if(ref == null) {
if(shouldLog)
@@ -414,16 +416,17 @@
props[1] = new Integer(triedNodes);
props[2] = new Integer(connectedNodes);
props[3] = new Integer(successNodes);
- props[4] = new Long(totalConnectAttempts);
- props[5] = new Long(totalConnectSuccesses);
- props[6] = new Float(pLegitDNF);
- props[7] = new Float(pSemiLegitDNF);
- props[8] = Long.toString(lowestEstimatedSearchTime)+"ms";
- props[9] = Long.toString(lowestEstimatedDNFTime)+"ms";
+ props[4] = new Integer(backedOffNodes);
+ props[5] = new Long(totalConnectAttempts);
+ props[6] = new Long(totalConnectSuccesses);
+ props[7] = new Float(pLegitDNF);
+ props[8] = new Float(pSemiLegitDNF);
+ props[9] = Long.toString(lowestEstimatedSearchTime)+"ms";
+ props[10] = Long.toString(lowestEstimatedDNFTime)+"ms";
- props[10] = new
String(globalEstimator.getHTMLReportingTool().lowestString(TimeEstimator.TIME));
- props[11] = new
String(globalEstimator.getHTMLReportingTool().highestString(TimeEstimator.TIME));
- props[12] = getClass().getName();
+ props[11] = new
String(globalEstimator.getHTMLReportingTool().lowestString(TimeEstimator.TIME));
+ props[12] = new
String(globalEstimator.getHTMLReportingTool().highestString(TimeEstimator.TIME));
+ props[13] = getClass().getName();
StringMap sm = new SimpleStringMap(TABLE_PROPERTIES, props);
// FIXME!
StringMap[] refs = new StringMap[refInfos.size()];
@@ -435,8 +438,8 @@
private final static String[] TABLE_PROPERTIES
= {"Number of node references", "Attempted to contact node references",
- "Contacted node references",
- "Connections with Successful Transfers", "Connection Attempts",
+ "Contacted node references", "Connections with Successful
Transfers",
+ "Backed off nodes", "Connection Attempts",
"Successful Connections", "Probability of legitimate DNF",
"Worse guess probability of legitimate DNF",
"Lowest max estimated search time", "Lowest max estimated DNF time",
Index: StandardNodeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/StandardNodeEstimator.java,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -w -r1.38 -r1.39
--- StandardNodeEstimator.java 13 Nov 2003 16:14:51 -0000 1.38
+++ StandardNodeEstimator.java 13 Nov 2003 20:49:54 -0000 1.39
@@ -15,6 +15,7 @@
import freenet.Core;
import freenet.FieldSet;
import freenet.Key;
+import freenet.crypt.RandomSource;
import freenet.node.Main;
import freenet.node.NodeReference;
import freenet.support.DataObjectPending;
@@ -52,6 +53,12 @@
int successes = 0;
boolean needConnection;
long lastEstimate = -1;
+ // Variables for exponential backoff on SearchFailed
+ long enteredBackoffTime = -1;
+ int defaultBackoffPeriod = 1000;
+ int currentBackoffPeriod = defaultBackoffPeriod;
+ RandomSource random;
+ long lastPartialSuccessTime;
public FieldSet toFieldSet() {
FieldSet fs = new FieldSet();
@@ -75,9 +82,10 @@
RoutingMemory mem,
RunningAverageFactory raf,
TimeEstimatorFactory
rtef,
DataObjectPending dop,
- boolean
needConnection) throws IOException {
+ boolean
needConnection, RandomSource rand) throws IOException {
Core.logger.log(this, "Serializing in StandardNodeEstimator",
Logger.MINOR);
+ this.random = rand;
this.ngrt = ngrt;
this.ref = ref;
this.mem = mem;
@@ -136,7 +144,7 @@
TimeEstimatorFactory
rtef, Key k,
double
initTransferRate,
boolean
needConnection, double maxPDNF,
- long maxSearchTime,
long maxDNFTime) {
+ long maxSearchTime,
long maxDNFTime, RandomSource rand) {
if(Core.logger.shouldLog(Logger.MINOR, this))
Core.logger.log(this, "New node in routing table
(StandardNodeEstimator impl) for "+
ref+" ("+ngrt+"), details:"+"mem = "+mem+",
key="+k+", initTransferRate="+
@@ -326,12 +334,38 @@
}
public void searchFailed(long time) {
+ // QueryRejected or timeout
rpSearchFailed.report(1);
rtSearchFailed.report(time);
boolean logDEBUG = Core.logger.shouldLog(Logger.DEBUG,this);
if(logDEBUG) Core.logger.log(this, "Search failed in "+time+"ms on
"+ref,
new Exception("debug"), Logger.DEBUG);
- lastAccessedTime = System.currentTimeMillis();
+ long now = System.currentTimeMillis();
+ lastAccessedTime = now;
+ // Exponential backoff
+ synchronized(this) {
+ if(enteredBackoffTime + currentBackoffPeriod > now) {
+ // Ignore, already backed off
+ if(logDEBUG)
+ Core.logger.log(this, "Ignored a searchFailed
because already backed off on "+this,
+ Logger.DEBUG);
+ } else {
+ if(lastPartialSuccessTime > enteredBackoffTime) {
+ // We have had a transfer/DNF since we backed
off
+ // Reset the backoff
+ currentBackoffPeriod = defaultBackoffPeriod;
+ } else {
+ // Hasn't been a transfer/DNF in the meantime
+ currentBackoffPeriod = currentBackoffPeriod +
+ random.nextInt(currentBackoffPeriod);
+ if(currentBackoffPeriod > Integer.MAX_VALUE/2)
+ currentBackoffPeriod =
Integer.MAX_VALUE/2;
+ }
+ enteredBackoffTime = now;
+ Core.logger.log(this, "Backing off "+this+" for
"+currentBackoffPeriod+
+ "ms", Logger.MINOR);
+ }
+ }
}
public void transferFailed(Key key, long time, long size) {
@@ -347,7 +381,7 @@
if(logDEBUG) Core.logger.log(this, "Transfer failed in "+time+"ms ("+
size+" bytes) on "+ref, new
Exception("debug"),
Logger.DEBUG);
- lastAccessedTime = System.currentTimeMillis();
+ lastAccessedTime = lastPartialSuccessTime = System.currentTimeMillis();
}
public void dataNotFound(Key key, long searchTime, int htl) {
@@ -360,7 +394,7 @@
etDNF.reportTime(key, searchTime/htl);
if(logDEBUG) Core.logger.log(this, "Data Not Found in "+searchTime+"ms
on "+ref,
new Exception("debug"), Logger.DEBUG);
- lastAccessedTime = System.currentTimeMillis();
+ lastAccessedTime = lastPartialSuccessTime = System.currentTimeMillis();
}
public void transferSucceeded(Key key, long searchTime, int htl,
@@ -372,7 +406,8 @@
synchronized(this) {
successes++;
}
- lastSuccessTime = System.currentTimeMillis();
+ lastSuccessTime = lastPartialSuccessTime = lastAccessedTime =
+ System.currentTimeMillis();
epDNFGivenNotSearchFailed.
reportProbability(key, 0);
rpDNF.report(0.0);
@@ -384,7 +419,6 @@
" bytes per second", rate > 100000 ?
Logger.NORMAL : Logger.DEBUG);
etTransferRate.reportTransferRate(key, rate*0.001); // convert
to bytes per millisecond
}
- lastAccessedTime = System.currentTimeMillis();
}
public int getDataLength() {
@@ -467,7 +501,8 @@
"Search died probability", "Transfer died probability",
"Search died time",
"Open Outbound Connections", "Open Inbound Connections",
- "Minimum Transfer Rate", "Maximum Transfer Rate" };
+ "Minimum Transfer Rate", "Maximum Transfer Rate",
+ "Backed Off Until", "Backoff Length"};
static class MyComparableStringMap
extends SimpleStringMap implements ComparableStringMap {
@@ -537,6 +572,13 @@
TimeEstimator.HTMLReportTool reportTool =
etTransferRate.getHTMLReportingTool();
values[18] = reportTool.lowestString(TimeEstimator.TRANSFER_RATE);
values[19] = reportTool.highestString(TimeEstimator.TRANSFER_RATE);
+ long backoffUntil = enteredBackoffTime + currentBackoffPeriod;
+ if(backoffUntil > now) {
+ values[20] = new Long(backoffUntil - now);
+ } else {
+ values[20] = new Long(0);
+ }
+ values[21] = new Integer(currentBackoffPeriod);
return new MyComparableStringMap(values);
}
@@ -918,5 +960,15 @@
return
(long)reportTool.convertFromRaw(etDNF.highestRaw(),
TimeEstimator.TIME);
+ }
+
+ /* (non-Javadoc)
+ * @see freenet.node.rt.NodeEstimator#isBackedOff()
+ */
+ public boolean isBackedOff() {
+ long now = System.currentTimeMillis();
+ if(enteredBackoffTime + currentBackoffPeriod > now)
+ return true;
+ else return false;
}
}
Index: NodeEstimator.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/rt/NodeEstimator.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -w -r1.16 -r1.17
--- NodeEstimator.java 13 Nov 2003 12:02:52 -0000 1.16
+++ NodeEstimator.java 13 Nov 2003 20:49:54 -0000 1.17
@@ -127,4 +127,9 @@
* Write to a FieldSet for FNP transfer. Leave out anything unsuitable for
transfer.
*/
abstract public FieldSet toFieldSet();
+
+ /**
+ * @return Whether we are currently backed off
+ */
+ abstract public boolean isBackedOff();
}
Index: StandardNodeEstimatorFactory.java
===================================================================
RCS file:
/cvsroot/freenet/freenet/src/freenet/node/rt/StandardNodeEstimatorFactory.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -w -r1.6 -r1.7
--- StandardNodeEstimatorFactory.java 13 Nov 2003 02:16:58 -0000 1.6
+++ StandardNodeEstimatorFactory.java 13 Nov 2003 20:49:54 -0000 1.7
@@ -6,6 +6,7 @@
import freenet.Core;
import freenet.FieldSet;
import freenet.Key;
+import freenet.crypt.RandomSource;
import freenet.node.NodeReference;
import freenet.support.DataObjectPending;
import freenet.support.Logger;
@@ -18,19 +19,22 @@
NGRoutingTable ngrt;
final RunningAverageFactory raf;
final TimeEstimatorFactory rtef;
+ final RandomSource rand;
public StandardNodeEstimatorFactory(NGRoutingTable ngrt,
RunningAverageFactory raf,
-
TimeEstimatorFactory rtef) {
+
TimeEstimatorFactory rtef, RandomSource rand) {
this.ngrt = ngrt;
this.raf = raf;
this.rtef = rtef;
+ this.rand = rand;
}
public StandardNodeEstimatorFactory(RunningAverageFactory raf,
-
TimeEstimatorFactory rtef) {
+
TimeEstimatorFactory rtef, RandomSource rand) {
this.raf = raf;
this.rtef = rtef;
+ this.rand = rand;
}
@@ -45,7 +49,7 @@
long maxSearchTime,
long maxDNFTime) {
// Create completely new NodeEstimator for the identity
NodeEstimator ne = new StandardNodeEstimator(ngrt, ref, mem, e, raf, rtef,
null,
- rate,
needConnection, maxPDNF, maxSearchTime, maxDNFTime);
+ rate,
needConnection, maxPDNF, maxSearchTime, maxDNFTime, rand);
if(Core.logger.shouldLog(Logger.DEBUG, this))
Core.logger.log(this, "Created new NodeEstimator from scratch: "+ne,
Logger.DEBUG);
return ne;
@@ -58,14 +62,14 @@
// Hrrm
// Serialize in from the DOP
return new StandardNodeEstimator(ngrt, ref, mem, raf, rtef, e,
-
needConnection);
+
needConnection, rand);
}
public NodeEstimator create(RoutingMemory mem, NodeReference ref,
FieldSet e, Key k,
double rate, boolean needConnection, double maxPDNF,
long maxSearchTime,
long maxDNFTime) {
NodeEstimator ne = new StandardNodeEstimator(ngrt, ref, mem, e, raf,
rtef, k, rate,
-
needConnection, maxPDNF, maxSearchTime, maxDNFTime);
+
needConnection, maxPDNF, maxSearchTime, maxDNFTime, rand);
if(Core.logger.shouldLog(Logger.DEBUG, this))
Core.logger.log(this, "Created new NodeEstimator from scratch:
"+ne, Logger.DEBUG);
return ne;
_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs