You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2008/12/09 20:38:44 UTC
svn commit: r724849 - in /tomcat/trunk/java/org/apache:
coyote/http11/Http11NioProcessor.java coyote/http11/Http11NioProtocol.java
coyote/http11/InternalNioInputBuffer.java tomcat/util/net/NioEndpoint.java
Author: fhanik
Date: Tue Dec 9 11:38:44 2008
New Revision: 724849
URL: http://svn.apache.org/viewvc?rev=724849&view=rev
Log:
Implement keep alive timeout, and while doing this, I realized that keepalive is either on or off, but there is no counter
Modified:
tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=724849&r1=724848&r2=724849&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Tue Dec 9 11:38:44 2008
@@ -208,8 +208,7 @@
* Maximum number of Keep-Alive requests to honor.
*/
protected int maxKeepAliveRequests = -1;
-
-
+
/**
* SSL enabled ?
*/
@@ -726,13 +725,15 @@
public SocketState event(SocketStatus status)
throws IOException {
- RequestInfo rp = request.getRequestProcessor();
+ long soTimeout = endpoint.getSoTimeout();
+ int keepAliveTimeout = endpoint.getKeepAliveTimeout();
+ RequestInfo rp = request.getRequestProcessor();
+ final NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment)socket.getAttachment(false);
try {
rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
error = !adapter.event(request, response, status);
if ( !error ) {
- NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment)socket.getAttachment(false);
if (attach != null) {
attach.setComet(comet);
if (comet) {
@@ -740,7 +741,11 @@
if (comettimeout != null) attach.setTimeout(comettimeout.longValue());
} else {
//reset the timeout
- attach.setTimeout(endpoint.getSocketProperties().getSoTimeout());
+ if (keepAlive && keepAliveTimeout>0) {
+ attach.setTimeout(keepAliveTimeout);
+ } else {
+ attach.setTimeout(soTimeout);
+ }
}
}
@@ -761,7 +766,6 @@
return SocketState.CLOSED;
} else if (!comet) {
recycle();
- //pay attention to the keep alive flag set in process()
return (keepAlive)?SocketState.OPEN:SocketState.CLOSED;
} else {
return SocketState.LONG;
@@ -791,15 +795,17 @@
keepAlive = true;
comet = false;
-
- int keepAliveLeft = maxKeepAliveRequests;
long soTimeout = endpoint.getSoTimeout();
+ int keepAliveTimeout = endpoint.getKeepAliveTimeout();
boolean keptAlive = false;
boolean openSocket = false;
boolean recycle = true;
+ final KeyAttachment ka = (KeyAttachment)socket.getAttachment(false);
+
while (!error && keepAlive && !comet) {
-
+ //always default to our soTimeout
+ ka.setTimeout(soTimeout);
// Parsing the request header
try {
if( !disableUploadTimeout && keptAlive && soTimeout > 0 ) {
@@ -810,6 +816,10 @@
//of the request line, we can't recycle the processor
openSocket = true;
recycle = false;
+ if (inputBuffer.getParsingRequestLinePhase()<2) {
+ //keep alive timeout here
+ if (keepAliveTimeout>0) ka.setTimeout(keepAliveTimeout);
+ }
break;
}
keptAlive = true;
@@ -851,8 +861,10 @@
response.setStatus(400);
error = true;
}
-
- if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0)
+
+ if (maxKeepAliveRequests == 1 )
+ keepAlive = false;
+ if (maxKeepAliveRequests > 0 && ka.decrementKeepAlive() <= 0)
keepAlive = false;
// Process the request in the adapter
@@ -916,7 +928,6 @@
// Do sendfile as needed: add socket to sendfile and end
if (sendfileData != null && !error) {
- KeyAttachment ka = (KeyAttachment)socket.getAttachment(false);
ka.setSendfileData(sendfileData);
sendfileData.keepAlive = keepAlive;
SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
@@ -928,10 +939,9 @@
rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
- }
+ }//while
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
-
if (comet) {
if (error) {
recycle();
@@ -940,7 +950,9 @@
return SocketState.LONG;
}
} else {
- if ( recycle ) recycle();
+ if ( recycle ) {
+ recycle();
+ }
//return (openSocket) ? (SocketState.OPEN) : SocketState.CLOSED;
return (openSocket) ? (recycle?SocketState.OPEN:SocketState.LONG) : SocketState.CLOSED;
}
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java?rev=724849&r1=724848&r2=724849&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java Tue Dec 9 11:38:44 2008
@@ -19,6 +19,7 @@
import java.net.InetAddress;
import java.net.URLEncoder;
+import java.nio.channels.SocketChannel;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
@@ -212,7 +213,6 @@
protected Hashtable<String, Object> attributes =
new Hashtable<String, Object>();
- private int maxKeepAliveRequests=100; // as in Apache HTTPD server
private int timeout = 300000; // 5 minutes as in Apache HTTPD server
private int maxSavePostSize = 4 * 1024;
private int maxHttpHeaderSize = 8 * 1024;
@@ -456,6 +456,14 @@
ep.setSoTimeout(i);
setAttribute("soTimeout", "" + i);
}
+
+ public void setKeepAliveTimeout(int keepAliveTimeout) {
+ ep.setKeepAliveTimeout(keepAliveTimeout);
+ }
+
+ public int getKeepAliveTimeout() {
+ return ep.getKeepAliveTimeout();
+ }
public String getProtocol() {
return getProperty("protocol");
@@ -477,13 +485,13 @@
}
public int getMaxKeepAliveRequests() {
- return maxKeepAliveRequests;
+ return ep.getMaxKeepAliveRequests();
}
/** Set the maximum number of Keep-Alive requests that we will honor.
*/
public void setMaxKeepAliveRequests(int mkar) {
- maxKeepAliveRequests = mkar;
+ ep.setMaxKeepAliveRequests(mkar);
setAttribute("maxKeepAliveRequests", "" + mkar);
}
@@ -491,7 +499,7 @@
* Return the Keep-Alive policy for the connection.
*/
public boolean getKeepAlive() {
- return ((maxKeepAliveRequests != 0) && (maxKeepAliveRequests != 1));
+ return ((ep.getMaxKeepAliveRequests() != 0) && (ep.getMaxKeepAliveRequests() != 1));
}
/**
@@ -638,6 +646,25 @@
recycledProcessors.clear();
}
+ public void release(SocketChannel socket) {
+ if (log.isDebugEnabled())
+ log.debug("Iterating through our connections to release a socket channel:"+socket);
+ boolean released = false;
+ Iterator<java.util.Map.Entry<NioChannel, Http11NioProcessor>> it = connections.entrySet().iterator();
+ while (it.hasNext()) {
+ java.util.Map.Entry<NioChannel, Http11NioProcessor> entry = it.next();
+ if (entry.getKey().getIOChannel()==socket) {
+ it.remove();
+ Http11NioProcessor result = entry.getValue();
+ result.recycle();
+ released = true;
+ break;
+ }
+ }
+ if (log.isDebugEnabled())
+ log.debug("Done iterating through our connections to release a socket channel:"+socket +" released:"+released);
+ }
+
public void release(NioChannel socket) {
Http11NioProcessor result = connections.remove(socket);
if ( result != null ) {
@@ -770,7 +797,7 @@
proto.maxHttpHeaderSize,
proto.ep);
processor.setAdapter(proto.adapter);
- processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests);
+ processor.setMaxKeepAliveRequests(proto.getMaxKeepAliveRequests());
processor.setTimeout(proto.timeout);
processor.setDisableUploadTimeout(proto.disableUploadTimeout);
processor.setCompressionMinSize(proto.compressionMinSize);
Modified: tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?rev=724849&r1=724848&r2=724849&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Tue Dec 9 11:38:44 2008
@@ -934,4 +934,9 @@
}
+ public int getParsingRequestLinePhase() {
+ return parsingRequestLinePhase;
+ }
+
+
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=724849&r1=724848&r2=724849&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Tue Dec 9 11:38:44 2008
@@ -366,6 +366,18 @@
}
public int getMaxThreads() { return maxThreads; }
+ /**
+ * Max keep alive requests
+ */
+ protected int maxKeepAliveRequests=100; // as in Apache HTTPD server
+ public int getMaxKeepAliveRequests() {
+ return maxKeepAliveRequests;
+ }
+ public void setMaxKeepAliveRequests(int maxKeepAliveRequests) {
+ this.maxKeepAliveRequests = maxKeepAliveRequests;
+ }
+
+
/**
* Priority of the worker threads.
@@ -421,6 +433,14 @@
public void setBacklog(int backlog) { if (backlog > 0) this.backlog = backlog; }
public int getBacklog() { return backlog; }
+ /**
+ * Keepalive timeout, if lesser or equal to 0 then soTimeout will be used.
+ */
+ protected int keepAliveTimeout = 0;
+ public void setKeepAliveTimeout(int keepAliveTimeout) { this.keepAliveTimeout = keepAliveTimeout; }
+ public int getKeepAliveTimeout() { return keepAliveTimeout;}
+
+
protected SocketProperties socketProperties = new SocketProperties();
/**
@@ -1367,6 +1387,7 @@
KeyAttachment key = keyCache.poll();
final KeyAttachment ka = key!=null?key:new KeyAttachment();
ka.reset(this,socket,getSocketProperties().getSoTimeout());
+ ka.setKeepAliveLeft(NioEndpoint.this.getMaxKeepAliveRequests());
PollerEvent r = eventCache.poll();
ka.interestOps(SelectionKey.OP_READ);//this is what OP_REGISTER turns into.
if ( r==null) r = new PollerEvent(socket,ka,OP_REGISTER);
@@ -1391,6 +1412,7 @@
}
if (ka!=null) handler.release(ka.getChannel());
+ else handler.release((SocketChannel)key.channel());
if (key.isValid()) key.cancel();
if (key.channel().isOpen()) try {key.channel().close();}catch (Exception ignore){}
try {ka.channel.close(true);}catch (Exception ignore){}
@@ -1713,6 +1735,7 @@
cometNotify = false;
cometOps = SelectionKey.OP_READ;
sendfileData = null;
+ keepAliveLeft = 100;
}
public void reset() {
@@ -1759,7 +1782,9 @@
}
public void startReadLatch(int cnt) { readLatch = startLatch(readLatch,cnt);}
public void startWriteLatch(int cnt) { writeLatch = startLatch(writeLatch,cnt);}
-
+ public int getKeepAliveLeft() { return this.keepAliveLeft; }
+ public void setKeepAliveLeft(int keepAliveLeft) { this.keepAliveLeft = keepAliveLeft;}
+ public int decrementKeepAlive() { return (--keepAliveLeft);}
protected void awaitLatch(CountDownLatch latch, long timeout, TimeUnit unit) throws InterruptedException {
if ( latch == null ) throw new IllegalStateException("Latch cannot be null");
@@ -1786,6 +1811,7 @@
protected CountDownLatch writeLatch = null;
protected long lastRegistered = 0;
protected SendfileData sendfileData = null;
+ protected int keepAliveLeft = 100;
}
// ------------------------------------------------ Application Buffer Handler
@@ -1825,6 +1851,7 @@
public SocketState event(NioChannel socket, SocketStatus status);
public void releaseCaches();
public void release(NioChannel socket);
+ public void release(SocketChannel socket);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org