Author: toad
Date: 2006-08-18 13:19:31 +0000 (Fri, 18 Aug 2006)
New Revision: 10186
Modified:
trunk/freenet/src/freenet/node/PeerManager.java
trunk/freenet/src/freenet/node/PeerNode.java
Log:
Make backoff an advisory rather than mandatory mechanism:
- It is basically a means of load BALANCING
- Load limiting is handled by the sender-side AIMD
- By making backoff mandatory, we may have been exacerbating the load problems
- The metaphor with ethernet collision detection is dubious
- Backoff does not enhance security; it may be a security issue in fact
- Mandatory backoff can prevent newbie or true darknet nodes with few
connections from being able to access Freenet at all
- It may be involved in long-term load oscillations
Please test, this may be mandatory soon.
Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java 2006-08-18 13:04:36 UTC
(rev 10185)
+++ trunk/freenet/src/freenet/node/PeerManager.java 2006-08-18 13:19:31 UTC
(rev 10186)
@@ -378,6 +378,7 @@
}
double bestDiff = 1.0;
double bestLoc = Double.MAX_VALUE;
+ boolean foundOne = false;
for(int i=0;i<peers.length;i++) {
PeerNode p = peers[i];
if(!p.isRoutable()) continue;
@@ -386,10 +387,26 @@
continue;
double diff = distance(peerloc, loc);
if(diff < bestDiff) {
+ foundOne = true;
bestDiff = diff;
bestLoc = peerloc;
}
}
+ if(!foundOne) {
+ for(int i=0;i<peers.length;i++) {
+ PeerNode p = peers[i];
+ // Ignore backoff state
+ double peerloc = p.getLocation().getValue();
+ if(Math.abs(peerloc - ignoreLoc) < Double.MIN_VALUE*2)
+ continue;
+ double diff = distance(peerloc, loc);
+ if(diff < bestDiff) {
+ foundOne = true;
+ bestDiff = diff;
+ bestLoc = peerloc;
+ }
+ }
+ }
return bestLoc;
}
@@ -420,6 +437,17 @@
bestDiff = diff;
}
}
+ if(best == null) {
+ // Ignore backoff; backoff is an advisory mechanism for load
BALANCING, not for load LIMITING
+ for(int i=0;i<peers.length;i++) {
+ PeerNode p = peers[i];
+ double diff = distance(p, loc);
+ if(diff < bestDiff) {
+ best = p;
+ bestDiff = diff;
+ }
+ }
+ }
return best;
}
@@ -438,25 +466,30 @@
else return Math.min (b - a, 1.0 - b + a);
}
- /**
+ /*
* FIXME
* This scans the same array 4 times. It would be better to scan once and
execute 4 callbacks...
* For this reason the metrics are only updated if advanced mode is enabled
*/
public PeerNode closerPeer(PeerNode pn, HashSet routedTo, HashSet
notIgnored, double loc, boolean ignoreSelf, boolean calculateMisrouting) {
- PeerNode best = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf,
false);
- if ((best != null) && calculateMisrouting) {
- PeerNode nbo = _closerPeer(pn, routedTo, notIgnored, loc,
ignoreSelf, true);
- if(nbo != null) {
- node.missRoutingDistance.report(distance(best,
nbo.getLocation().getValue()));
- int numberOfConnected =
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_CONNECTED);
- int numberOfRoutingBackedOff =
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
- if (numberOfRoutingBackedOff + numberOfConnected > 0 ) {
- node.backedoffPercent.report((double)
numberOfRoutingBackedOff / (double) (numberOfRoutingBackedOff +
numberOfConnected));
- }
- }
- }
- return best;
+ PeerNode best = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf,
false);
+ if(best == null) {
+ // Backoff is an advisory mechanism for balancing rather than
limiting load.
+ // So send a request even though everything is backed off.
+ return _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf,
true);
+ }
+ if (calculateMisrouting) {
+ PeerNode nbo = _closerPeer(pn, routedTo, notIgnored, loc,
ignoreSelf, true);
+ if(nbo != null) {
+ node.missRoutingDistance.report(distance(best,
nbo.getLocation().getValue()));
+ int numberOfConnected =
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_CONNECTED);
+ int numberOfRoutingBackedOff =
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
+ if (numberOfRoutingBackedOff + numberOfConnected > 0 ) {
+ node.backedoffPercent.report((double)
numberOfRoutingBackedOff / (double) (numberOfRoutingBackedOff +
numberOfConnected));
+ }
+ }
+ }
+ return best;
}
/**
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2006-08-18 13:04:36 UTC
(rev 10185)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2006-08-18 13:19:31 UTC
(rev 10186)
@@ -754,7 +754,8 @@
}
/**
- * Is this peer currently connected?
+ * Is this peer currently connected? (And routing-compatible, i.e. can we
route
+ * requests to it, ignoring backoff)
*
* Note possible deadlocks! PeerManager calls this, we call
* PeerManager in e.g. verified.