Here is a tentative rollout of non-blocking polling for live connections, assuming everything else (handshaking, authentication & trailing field stuff) stays blocking. This should save 30-40% of threads used. If authentication is also nio'd that percentage will rise to above 50.
1. change all sockets used in fred to use channels. The changes to the code are minimal (and already done in my local copy) but break compatibility with jre's older than 1.4. 1.5 (optional) make the FNP and FCP interfaces non-blocking, thus saving one thread. Again code changes are minimal. 2. After a connection is established on an interface and the handshake/authentication is complete, change the socket to non-blocking mode and pass it on to the object doing the select loop. 3. Implement the select loop. It will run in a single thread which is recommended to have higher priority than the others. The object representing the select loop will keep track of all open connections (through connection handlers) and those who are receiving trailing fields will be marked. The ConnectionHandler object will be augmented with a flag whether its processing trailing field and with a buffer holding received data. The basic operation of this select loop is the following: 3.1. block for any network input on the open connections for a specified timeout (20-200ms?) 3.2. query those ConnectionHandlers that have been registered as reading trailing fields, and if any of them have completed their reads re-register their channels to the selector. 3.3 Read the available data and put it in the buffers of the appropriate ConnectionHandlers 3.3.a) If the received data contains an "EndMessage", enter the message parsing code and produce a messageObject. I'm assuming those messageObjects are afterwards taken care of separate threads. 3.3.b) If the received data contains an "Storable=", mark the ConnectionHandler as busy, unregister it from the selector and change the appropriate socket to blocking mode. After that enter the code that deals with trailing fields in a separate thread. 3.3.c) If neither of those is there, return and process the next ConnectionHandler. 3.4 Register to the selector any newly opened connections passed from the interface. Other than implementing the loop, changes include checking whether a complete message has been received before running the ConnectionHandler.run() method. In that method the streams will have to be backed either by a String or byte[]. No changes are required to the code that deals with trailing fields because blocking streams work fine with blocking sockets, except that right before dying the thread that reads the trailing fields must mark the ConnectionHandler as available and wakeup() the selector. All in all, the amount of code changes is not as big as first expected. If the authors of the current code don't mind being bothered by me asking questions every so often, the transition can be done in 1-1.5 months. Perhaps even less. _______________________________________________ devl mailing list devl at freenetproject.org http://hawk.freenetproject.org:8080/cgi-bin/mailman/listinfo/devl