[jboss-cvs] JBossRemoting/src/main/org/jboss/remoting/transport/socket ...
Tom Elrod
tom.elrod at jboss.com
Fri Nov 3 11:19:16 EST 2006
User: telrod
Date: 06/11/03 11:19:16
Modified: src/main/org/jboss/remoting/transport/socket
SocketServerInvoker.java ServerThread.java
Log:
JBREM-607 - adding idle server thread cleanup for thread pool on server side.
Revision Changes Path
1.31 +141 -21 JBossRemoting/src/main/org/jboss/remoting/transport/socket/SocketServerInvoker.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: SocketServerInvoker.java
===================================================================
RCS file: /cvsroot/jboss/JBossRemoting/src/main/org/jboss/remoting/transport/socket/SocketServerInvoker.java,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- SocketServerInvoker.java 29 Oct 2006 03:40:53 -0000 1.30
+++ SocketServerInvoker.java 3 Nov 2006 16:19:16 -0000 1.31
@@ -25,6 +25,7 @@
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.ServerInvoker;
import org.jboss.remoting.marshal.serializable.SerializableMarshaller;
+import org.jboss.remoting.util.TimerUtil;
import org.jboss.util.propertyeditor.PropertyEditors;
import javax.net.ServerSocketFactory;
@@ -37,13 +38,14 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import java.util.TimerTask;
/**
* SocketServerInvoker is the server-side of a SOCKET based transport
*
* @author <a href="mailto:jhaynie at vocalocity.net">Jeff Haynie</a>
* @author <a href="mailto:tom.elrod at jboss.com">Tom Elrod</a>
- * @version $Revision: 1.30 $
+ * @version $Revision: 1.31 $
* @jmx:mbean
*/
public class SocketServerInvoker extends ServerInvoker implements Runnable, SocketServerInvokerMBean
@@ -83,6 +85,10 @@
protected boolean reuseAddress = true;
+ // defaults to -1 as to not have idle timeouts
+ protected int idleTimeout = -1;
+ protected IdleTimerTask idleTimerTask = null;
+
/**
* The logging trace level flag
*/
@@ -214,6 +220,24 @@
acceptThreads[i].start();
}
}
+
+ if(idleTimeout > 0)
+ {
+ if(idleTimerTask != null)
+ {
+ idleTimerTask.cancel();
+ }
+ idleTimerTask = new IdleTimerTask();
+ TimerUtil.schedule(idleTimerTask, idleTimeout * 1000);
+ }
+ else
+ {
+ if(idleTimerTask != null)
+ {
+ idleTimerTask.cancel();
+ }
+ }
+
}
protected ServerSocket createServerSocket(int serverBindPort, int backlog, InetAddress bindAddress) throws IOException
@@ -423,6 +447,44 @@
}
+ public int getIdleTimeout()
+ {
+ return idleTimeout;
+ }
+
+ /**
+ * Sets the timeout for idle threads to be removed from pool.
+ * If the value is greater than 0, then idle timeout will be
+ * activated, otherwise no idle timeouts will occur. By default,
+ * this value is -1.
+ *
+ * @param idleTimeout number of seconds before a idle thread is timed out.
+ */
+ public void setIdleTimeout(int idleTimeout)
+ {
+ this.idleTimeout = idleTimeout;
+
+ if(isStarted())
+ {
+ if(idleTimeout > 0)
+ {
+ if(idleTimerTask != null)
+ {
+ idleTimerTask.cancel();
+ }
+ idleTimerTask = new IdleTimerTask();
+ TimerUtil.schedule(idleTimerTask, idleTimeout * 1000);
+ }
+ else
+ {
+ if(idleTimerTask != null)
+ {
+ idleTimerTask.cancel();
+ }
+ }
+ }
+ }
+
public void run()
{
if(trace)
@@ -615,4 +677,62 @@
}
}
+ /**
+ * The IdleTimerTask is used to periodically check the server threads to
+ * see if any have been idle for a specified amount of time, and if so,
+ * release those threads and their connections and clear from the server
+ * thread pool.
+ */
+ public class IdleTimerTask extends TimerTask
+ {
+ public void run()
+ {
+ Object[] svrThreadArray = null;
+
+ synchronized(clientpool)
+ {
+ Set svrThreads = clientpool.getContents();
+ svrThreadArray = svrThreads.toArray();
+}
+ if(trace)
+ {
+ if(svrThreadArray != null)
+ {
+ log.trace("Idle timer task fired. Number of ServerThreads = " + svrThreadArray.length);
+ }
+ }
+
+ // iterate through pooled server threads and evict idle ones
+ if(svrThreadArray != null)
+ {
+ long currentTime = System.currentTimeMillis();
+
+ for(int x = 0; x < svrThreadArray.length; x++)
+ {
+ ServerThread svrThread = (ServerThread)svrThreadArray[x];
+
+ // check the idle time and evict
+ long idleTime = currentTime - svrThread.getLastRequestTimestamp();
+
+ if(trace)
+ {
+ log.trace("Idle time for ServerThread (" + svrThread + ") is " + idleTime);
+ }
+
+ long idleTimeout = getIdleTimeout() * 1000;
+ if(idleTime > idleTimeout)
+ {
+ if(trace)
+ {
+ log.trace("Idle timeout reached for ServerThread (" + svrThread + ") and will be evicted.");
+ }
+ clientpool.remove(svrThread);
+ svrThread.shutdown();
+ svrThread.unblock();
+ }
+ }
+ }
+ }
+ }
+
}
1.30 +30 -1 JBossRemoting/src/main/org/jboss/remoting/transport/socket/ServerThread.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: ServerThread.java
===================================================================
RCS file: /cvsroot/jboss/JBossRemoting/src/main/org/jboss/remoting/transport/socket/ServerThread.java,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- ServerThread.java 26 Sep 2006 02:27:52 -0000 1.29
+++ ServerThread.java 3 Nov 2006 16:19:16 -0000 1.30
@@ -58,7 +58,7 @@
*
* @author <a href="mailto:bill at jboss.org">Bill Burke</a>
* @author <a href="mailto:tom at jboss.org">Tom Elrod</a>
- * @version $Revision: 1.29 $
+ * @version $Revision: 1.30 $
*/
public class ServerThread extends Thread
{
@@ -87,6 +87,11 @@
*/
private boolean shouldCheckConnection = false;
+ /**
+ * Will indicate when the last request has been processed (used in determining
+ * idle connection/thread timeout)
+ */
+ private long lastRequestHandledTimestamp = System.currentTimeMillis();
public static synchronized int nextID()
{
@@ -119,6 +124,11 @@
}
}
+ public long getLastRequestTimestamp()
+ {
+ return lastRequestHandledTimestamp;
+ }
+
public void shutdown()
{
shutdown = true;
@@ -240,6 +250,23 @@
}
}
+ /**
+ * This method is intended to be used when need to unblock
+ * I/O read, which the thread will automatically loop back to
+ * do after processing a request. Calling this method will cause
+ * the underlying socket to be closed.
+ */
+ public void unblock()
+ {
+ try
+ {
+ socketWrapper.close();
+ }
+ catch (IOException e)
+ {
+ log.warn("Error closing socket when attempting to unblock I/O", e);
+ }
+ }
public synchronized void wakeup(Socket socket, int timeout, Map metadata) throws Exception
{
@@ -496,6 +523,8 @@
versionedWrite(outputStream, invoker, this.getClass().getClassLoader(), resp, version);
}
handlingResponse = false;
+ // set the timestamp for last successful processed request
+ lastRequestHandledTimestamp = System.currentTimeMillis();
}
private boolean isOneway(Map metadata)
More information about the jboss-cvs-commits
mailing list