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.


Reply via email to