Update of /cvsroot/freenet/freenet/src/freenet
In directory sc8-pr-cvs1:/tmp/cvs-serv24104/src/freenet
Modified Files:
ConnectionHandler.java OpenConnectionManager.java
Log Message:
Move KillSurplusConnections back out of a thread, but do it smarter. We will now keep
a queue of closed connections to try and avoid even needing to search for closed
connections to remove from the OCM. Many other speedups to KillSurplusConnections
MultiValueTable has a new method - countAll(id) to get a count of connections to a
peer (or whatever)
Index: ConnectionHandler.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/ConnectionHandler.java,v
retrieving revision 1.160
retrieving revision 1.161
diff -u -r1.160 -r1.161
--- ConnectionHandler.java 23 Sep 2003 00:55:09 -0000 1.160
+++ ConnectionHandler.java 26 Sep 2003 22:38:34 -0000 1.161
@@ -1022,6 +1022,7 @@
Core.logger.log(this, "Trailer chunk send failed for
"+this+
", closing",
Logger.MINOR);
sendClosed.change(true);
+ ocm.markClosed(this);
sendingCount = 0;
synchronized(trailerSendLock) {
sendingTrailerChunk = false;
Index: OpenConnectionManager.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/OpenConnectionManager.java,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -r1.108 -r1.109
--- OpenConnectionManager.java 26 Sep 2003 02:02:08 -0000 1.108
+++ OpenConnectionManager.java 26 Sep 2003 22:38:34 -0000 1.109
@@ -53,6 +53,8 @@
private int openConns;
private Object openConnsSync = new Object();
+ private LinkedList closedList = new LinkedList();
+
private final LRUQueue lru = new LRUQueue();
// Queue of blacklisted peers
private final BlackLRUQueue blq = new BlackLRUQueue(60000,100,3);
@@ -73,10 +75,6 @@
logDEBUG = Core.logger.shouldLog(Logger.DEBUG, this);
chs = new MultiValueTable(50, 3);
openConns = 0;
- SurplusKiller sk = new SurplusKiller(lru,maxConnections);
- Thread skt = new Thread(sk,"Surplus connection killing thread");
- skt.setDaemon(true);
- skt.start();
}
/**
@@ -108,8 +106,11 @@
synchronized(openConnsSync) {
openConns++;
}
+ if ( maxConnections != 0 && lru.size() < maxConnections ) return;
synchronized(lru) {
- lru.notifyAll();
+ /* At toad's request moving back to diong this in every thred. */
+// lru.notifyAll();
+ KillSurplusConnections();
}
}
@@ -231,6 +232,12 @@
id, Logger.DEBUG);
return null;
}
+
+ public void markClosed(ConnectionHandler ch) {
+ synchronized(closedList) {
+ closedList.addFirst(ch);
+ }
+ }
/**
* This attempts to search for the open connection to id best suited for
@@ -303,13 +310,8 @@
}
protected final boolean onlyRTNodeConn(Identity id) {
- if(!Main.node.rt.references(id))
- return false;
- Enumeration e = chs.getAll(id);
- if(!e.hasMoreElements()) return true; // it has zero
- e.nextElement();
- if(!e.hasMoreElements()) return true; // it has one
- else return false; // it has more than one
+ if ( chs.countAll(id) <= 1 && Main.node.rt.references(id) ) return
true;
+ else return false; // it has more than one or is not in the route
}
public int countOutboundConnections(Identity id) {
@@ -476,74 +478,71 @@
* Kills off one or more connections to ensure that we stay below the
connection limit
* This method is appropriate to call after a connection has been added to the
OCM
*/
- private class SurplusKiller implements Runnable {
-
- private LRUQueue lru;
- private int maxConnections;
-
- public SurplusKiller(LRUQueue lru,int maxConnections) {
- this.lru = lru;
- this.maxConnections = maxConnections;
- }
-
- public void run() {
- while (true) {
- // Dump LRU idle connection.
- //
- // Note: You don't want to dump the simple LRU connection
- // because under heavy load the LRU connections are
- // the ones that are transferring data.
- //
- ConnectionHandler oldest = null;
- while (true) {
- synchronized (lru) {
- if ( !(maxConnections > 0 && lru.size() > maxConnections) ) {
- try {
- // wait till we are awakened - no more need to die
- lru.wait();
- } catch ( InterruptedException ie ) {
+ private void KillSurplusConnections() {
+ // Dump LRU idle connection.
+ //
+ // Note: You don't want to dump the simple LRU connection
+ // because under heavy load the LRU connections are
+ // the ones that are transferring data.
+ //
+ ConnectionHandler oldest = null;
+ ConnectionHandler cached = null;
+ boolean oldestCache = false;
+ boolean candidateCache = false;
+ while (true) {
+ if ( maxConnections > 0 && lru.size() > maxConnections ) {
+ synchronized(closedList) {
+ if ( !closedList.isEmpty() ) {
+ oldest = (ConnectionHandler)closedList.removeLast();
+ }
+ }
+ // Dump an idle connection if possible.
+ if ( oldest == null ) for (Enumeration e = lru.elements();
e.hasMoreElements();) {
+ ConnectionHandler candidate =
+ (ConnectionHandler)e.nextElement();
+ if (!(candidate.sending() || candidate.receiving())) {
+ // If the oldest is open and the candidate is closed...
+ if( !candidate.isOpen() ) {
+ oldest = candidate;
+ break;
+ } else if ( oldest != null ) {
+ //This can only happen if it closes during the run of
+ //this loop, very unlikely but _anything_ which could
+ //keep us from running onlyRTNodeConn is a good thing
+ //because that involves locking hashtables, BigInteger
+ //math and badness like that.
+ if ( oldest != null && (!oldest.isOpen()) )
+ break;
+ // If the oldest is an only-conn-to-this-RTNode and the
+ // candidate is not... then use the candidate
+ if ( ( ( oldest == cached && oldestCache ) ||
+ ( oldestCache = onlyRTNodeConn(oldest) ) ) &&
+ ! ( candidateCache = onlyRTNodeConn(candidate) ) ) {
+ oldest = candidate;
+ oldestCache = candidateCache;
}
+ cached = oldest;
} else {
- // Dump an idle connection if possible.
- for (Enumeration e = lru.elements();
e.hasMoreElements();) {
- ConnectionHandler candidate =
- (ConnectionHandler)e.nextElement();
- if (!(candidate.sending() || candidate.receiving())) {
- // If the oldest is open and the candidate is
closed...
- if( !candidate.isOpen() ) {
- oldest = candidate;
- break;
- } else if ( oldest != null ) {
- //This can only happen if it closes during
the run of
- //this loop, very unlikely but _anything_
which could
- //keep us from running onlyRTNodeConn is a
good thing
- //because that involves locking hashtables,
BigInteger
- //math and badness like that.
- if ( oldest != null && (!oldest.isOpen()) )
- break;
- // If the oldest is an
only-conn-to-this-RTNode and the
- // candidate is not... then use the candidate
- if(onlyRTNodeConn(oldest) &&
(!onlyRTNodeConn(candidate)) )
- oldest = candidate;
- } else {
- oldest = candidate;
- }
- }
- }
- if (oldest == null) {
- // Not good. This connection will most likely
- // be restarted, causing even more traffic :-(
- oldest = (ConnectionHandler)lru.pop();
- }
-
+ oldest = candidate;
}
}
- if (oldest != null) {
- Core.diagnostics.occurrenceBinomial("connectionTimedout", 1,
0);
- oldest.terminate();
- oldest = null;
- }
}
+ if (oldest == null) {
+ // Not good. This connection will most likely
+ // be restarted, causing even more traffic :-(
+ oldest = (ConnectionHandler)lru.pop();
+ } else {
+ lru.remove(oldest);
+ }
+
+ } else {
+ //We have killed enough connections
+ return;
+ }
+ if (oldest != null) {
+ Core.diagnostics.occurrenceBinomial("connectionTimedout", 1, 0);
+ oldest.terminate();
+ oldest = null;
}
}
}
_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs