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;