Author: zothar
Date: 2006-06-11 17:13:35 +0000 (Sun, 11 Jun 2006)
New Revision: 9154

Modified:
   trunk/freenet/src/freenet/node/ARKFetcher.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/PacketSender.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/Version.java
Log:
803: Introduce ARKFetchManager, which handles a FIFO queue of ARKFetchers 
wanting to fetch and starts them via a PacketSender timed job Runnable, getting 
them off of PacketSender's code path.  Queueing to FIFO is much faster for 
PacketSender, thus improving node performance.

Modified: trunk/freenet/src/freenet/node/ARKFetcher.java
===================================================================
--- trunk/freenet/src/freenet/node/ARKFetcher.java      2006-06-11 14:53:52 UTC 
(rev 9153)
+++ trunk/freenet/src/freenet/node/ARKFetcher.java      2006-06-11 17:13:35 UTC 
(rev 9154)
@@ -40,18 +40,26 @@
        }

        /**
-        * Called when the node starts / is added, and also when we fail to 
connect twice 
-        * after a new reference. (So we get one from the ARK, we wait for the 
current
-        * connect attempt to fail, we start another one, that fails, we start 
another one,
-        * that also fails, so we try the fetch again to see if we can find 
something more
-        * recent).
+        * Called when we fail to connect twice after a new reference. (So we 
get one from
+        * the ARK, we wait for the current connect attempt to fail, we start 
another one,
+        * that fails, we start another one, that also fails, so we try the 
fetch again to
+        * see if we can find something more recent).
         */
+       public synchronized void queue() {
+               Logger.normal( this, "Queueing ARK Fetcher after 
"+peer.getHandshakeCount()+" failed handshakes for "+peer.getPeer()+" with 
identity '"+peer.getIdentityString()+"'");
+               node.arkFetchManager.addReadyARKFetcher(this);
+       }
+
+       /**
+        * Called when the ARKFetchManager says it's our turn to start fetching.
+        */
        public synchronized void start() {
                ClientGetter cg = null;
                if(started) {  // We only need one ARKFetcher per PeerNode
                  return;
                }
                Logger.minor(this, "Starting ... for "+peer+" on "+this);
+               Logger.normal( this, "Starting ARK Fetcher after 
"+peer.getHandshakeCount()+" failed handshakes for "+peer.getPeer()+" with 
identity '"+peer.getIdentityString()+"'");
                started = true;
                // Start fetch
                shouldRun = true;
@@ -96,6 +104,7 @@
                        started = false;
                        if(isFetching) {
                                node.removeARKFetcher(identity,this);
+                               
node.arkFetchManager.removeReadyARKFetcher(this);
                                isFetching = false;
                        }
                }
@@ -151,7 +160,7 @@
                if(!shouldRun) return;
                if(e.newURI != null) {
                        peer.updateARK(e.newURI);
-                       node.ps.queueTimedJob(new Runnable() { public void 
run() { start(); }}, backoff);  // Runnable rather than FastRunnable so we 
don't put ourselves on the PacketSender thread anyway
+                       queueWithBackoff();
                        return;
                }
                backoff += backoff;
@@ -159,7 +168,7 @@
                Logger.minor(this, "Failed to fetch ARK for "+peer+", now 
backing off ARK fetches for "+(int) (backoff / 1000)+" seconds");
                // We may be on the PacketSender thread.
                // FIXME should this be exponential backoff?
-               node.ps.queueTimedJob(new Runnable() { public void run() { 
start(); }}, backoff);  // Runnable rather than FastRunnable so we don't put 
ourselves on the PacketSender thread anyway
+               queueWithBackoff();
        }

        public void onSuccess(BaseClientPutter state) {
@@ -178,4 +187,19 @@
                return isFetching;
        }

+       /**
+        * Queue a Runnable on the PacketSender timed job queue to be run 
almost immediately
+        * Should not be called from other objects except for ARKFetchManager
+        */
+       public void queueRunnableImmediately() {
+               node.ps.queueTimedJob(new Runnable() { public void run() { 
start(); }}, 100);  // Runnable rather than FastRunnable so we don't put it on 
the PacketSender thread
+       }
+       
+       /**
+        * Queue a Runnable on the PacketSender timed job queue to be run 
almost immediately
+        * Should not be called from other objects except for ARKFetchManager
+        */
+       private void queueWithBackoff() {
+               node.ps.queueTimedJob(new Runnable() { public void run() { 
queue(); }}, backoff);  // Runnable rather than FastRunnable so we don't put it 
on the PacketSender thread
+       }
 }

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-06-11 14:53:52 UTC (rev 
9153)
+++ trunk/freenet/src/freenet/node/Node.java    2006-06-11 17:13:35 UTC (rev 
9154)
@@ -486,6 +486,10 @@
     private final long oldestNeverConnectedPeerAgeUpdateInterval = 5000;
     /** age of oldest never connected peer (milliseconds) */
     private long oldestNeverConnectedPeerAge = 0;
+    /** Next time to start a ready ARKFetcher */
+    private long nextReadyARKFetcherStartTime = -1;
+    /** Ready ARKFetcher start interval (milliseconds) */
+    private final long readyARKFetcherStartInterval = 1000;

     private final HashSet runningUIDs;

@@ -497,6 +501,7 @@
     String myName;
     final LocationManager lm;
     final PeerManager peers; // my peers
+    final ARKFetchManager arkFetchManager; // ready ARK Fetchers
     /** Directory to put node, peers, etc into */
     final File nodeDir;
     final File tempDir;
@@ -1165,6 +1170,9 @@
             }
         }

+               // Prepare the ARKFetchManager
+               arkFetchManager = new ARKFetchManager(this);
+
         // Then read the peers
         peers = new PeerManager(this, new File(nodeDir, 
"peers-"+portNumber).getPath());
         peers.writePeers();
@@ -3092,4 +3100,20 @@
                        }
                }
     }
+
+       /**
+        * Start a ready ARKFetcher if the timer has expired
+        */
+       public void maybeStartAReadyARKFetcher(long now) {
+         if(now > nextReadyARKFetcherStartTime) {
+               if(arkFetchManager.hasReadyARKFetchers()) {
+                       if(getNumARKFetchers() >= 30) {
+                               Logger.error(this, "Not starting ARKFetcher in 
maybeStartAReadyARKFetcher() because there are already 30 or more ARK Fetchers 
running");
+                       } else {
+                               arkFetchManager.maybeStartNextReadyARKFetcher();
+                       }
+               }
+               nextReadyARKFetcherStartTime = now + 
readyARKFetcherStartInterval;
+         }
+       }
 }

Modified: trunk/freenet/src/freenet/node/PacketSender.java
===================================================================
--- trunk/freenet/src/freenet/node/PacketSender.java    2006-06-11 14:53:52 UTC 
(rev 9153)
+++ trunk/freenet/src/freenet/node/PacketSender.java    2006-06-11 17:13:35 UTC 
(rev 9154)
@@ -142,6 +142,7 @@
         }
         node.maybeLogPeerNodeStatusSummary(now);
         node.maybeUpdateOldestNeverConnectedPeerAge(now);
+        node.maybeStartAReadyARKFetcher(now);
         long nextActionTime = Long.MAX_VALUE;
         long oldTempNow = now;
         for(int i=0;i<nodes.length;i++) {

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2006-06-11 14:53:52 UTC 
(rev 9153)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2006-06-11 17:13:35 UTC 
(rev 9154)
@@ -854,18 +854,12 @@
             this.handshakeCount++;
         }
         // Don't fetch ARKs for peers we have verified (through handshake) to 
be incompatible with us
-        if(handshakeCount >= MAX_HANDSHAKE_COUNT && 
!(verifiedIncompatibleOlderVersion || verifiedIncompatibleNewerVersion)) {
-               int numARKFetchers = node.getNumARKFetchers();
-               if( numARKFetchers >= 30 ) {  // Limit concurrent ARK Fetch 
Requests to 30 since we UserAlert at 20 disconnected peers anyway
-                               Logger.minor( this, "Not starting ARK Fetcher 
after "+handshakeCount+" failed handshakes for "+getPeer()+" with identity 
'"+getIdentityString()+"' because there are already 30 ARK Fetchers running.");
-               } else {
-                               Logger.normal( this, "Starting ARK Fetcher 
after "+handshakeCount+" failed handshakes for "+getPeer()+" with identity 
'"+getIdentityString()+"'");
-                               long arkFetcherStartTime1 = 
System.currentTimeMillis();
-                               arkFetcher.start();
-                               long arkFetcherStartTime2 = 
System.currentTimeMillis();
-                               if((arkFetcherStartTime2 - 
arkFetcherStartTime1) > 500) {
-                                       Logger.normal(this, 
"arkFetcherStartTime2 is more than half a second after arkFetcherStartTime1 
("+(arkFetcherStartTime2 - arkFetcherStartTime1)+") working on "+myName);
-                               }
+        if(handshakeCount == MAX_HANDSHAKE_COUNT && 
!(verifiedIncompatibleOlderVersion || verifiedIncompatibleNewerVersion)) {
+                       long arkFetcherStartTime1 = System.currentTimeMillis();
+                       arkFetcher.queue();
+                       long arkFetcherStartTime2 = System.currentTimeMillis();
+                       if((arkFetcherStartTime2 - arkFetcherStartTime1) > 500) 
{
+                               Logger.normal(this, "arkFetcherStartTime2 is 
more than half a second after arkFetcherStartTime1 ("+(arkFetcherStartTime2 - 
arkFetcherStartTime1)+") working on "+myName);
                        }
         }
     }
@@ -1917,5 +1911,9 @@
        public boolean isFetchingARK() {
                return arkFetcher.isFetching();
        }
+
+       public int getHandshakeCount() {
+               return handshakeCount;
+       }
 }


Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-06-11 14:53:52 UTC (rev 
9153)
+++ trunk/freenet/src/freenet/node/Version.java 2006-06-11 17:13:35 UTC (rev 
9154)
@@ -18,7 +18,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 802;
+       private static final int buildNumber = 803;

        /** Oldest build of Fred we will talk to */
        private static final int lastGoodBuild = 765;


Reply via email to