Author: fhanik
Date: Mon Dec 20 21:01:37 2010
New Revision: 1051291
URL: http://svn.apache.org/viewvc?rev=1051291&view=rev
Log:
Implement maxConnections for NIO connector
Modified:
tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
tomcat/trunk/test/org/apache/catalina/connector/TestMaxConnections.java
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1051291&r1=1051290&r2=1051291&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Mon Dec
20 21:01:37 2010
@@ -32,6 +32,7 @@ import org.apache.juli.logging.Log;
import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tomcat.util.net.jsse.JSSESocketFactory;
import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.threads.CounterLatch;
import org.apache.tomcat.util.threads.ResizableExecutor;
import org.apache.tomcat.util.threads.TaskQueue;
import org.apache.tomcat.util.threads.TaskThreadFactory;
@@ -123,6 +124,11 @@ public abstract class AbstractEndpoint {
protected volatile boolean internalExecutor = false;
/**
+ * counter for nr of connections handled by an endpoint
+ */
+ protected volatile CounterLatch connectionCounterLatch = null;
+
+ /**
* Socket properties
*/
protected SocketProperties socketProperties = new SocketProperties();
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java?rev=1051291&r1=1051290&r2=1051291&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Mon Dec 20
21:01:37 2010
@@ -109,7 +109,7 @@ public class JIoEndpoint extends Abstrac
return false;
}
- protected CounterLatch connectionCounterLatch = null;
+
// ------------------------------------------------ Handler Inner Interface
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=1051291&r1=1051290&r2=1051291&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Mon Dec 20
21:01:37 2010
@@ -57,6 +57,7 @@ import org.apache.tomcat.util.net.Abstra
import org.apache.tomcat.util.net.SecureNioChannel.ApplicationBufferHandler;
import org.apache.tomcat.util.net.jsse.JSSESocketFactory;
import org.apache.tomcat.util.net.jsse.NioX509KeyManager;
+import org.apache.tomcat.util.threads.CounterLatch;
/**
* NIO tailored thread pool, providing the following services:
@@ -567,6 +568,7 @@ public class NioEndpoint extends Abstrac
running = true;
paused = false;
+ connectionCounterLatch = new CounterLatch(0, getMaxConnections());
// Create worker collection
if ( getExecutor() == null ) {
createExecutor();
@@ -598,6 +600,8 @@ public class NioEndpoint extends Abstrac
*/
@Override
public void stopInternal() {
+ connectionCounterLatch.releaseAll();
+ connectionCounterLatch = null;
if (!paused) {
pause();
}
@@ -808,6 +812,8 @@ public class NioEndpoint extends Abstrac
break;
}
try {
+ //if we have reached max connections, wait
+ connectionCounterLatch.await();
// Accept the next incoming connection from the server
socket
SocketChannel socket = serverSock.accept();
// Hand this socket off to an appropriate processor
@@ -824,7 +830,9 @@ public class NioEndpoint extends Abstrac
if (log.isDebugEnabled())
log.debug("", ix);
}
- }
+ } else {
+ connectionCounterLatch.countUp();
+ }
}
} catch (SocketTimeoutException sx) {
//normal condition
@@ -1056,7 +1064,12 @@ public class NioEndpoint extends Abstrac
if (key.channel().isOpen()) try {key.channel().close();}catch
(Exception ignore){}
try {if (ka!=null) ka.getSocket().close(true);}catch
(Exception ignore){}
try {if (ka!=null && ka.getSendfileData()!=null &&
ka.getSendfileData().fchannel!=null && ka.getSendfileData().fchannel.isOpen())
ka.getSendfileData().fchannel.close();}catch (Exception ignore){}
- if (ka!=null) ka.reset();
+ if (ka!=null) {
+ ka.reset();
+ if (connectionCounterLatch.countDown()<0) {
+ log.warn("Incorrect connection count, multiple cancel
called on the same key?" );
+ }
+ }
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
if ( log.isDebugEnabled() ) log.error("",e);
Modified:
tomcat/trunk/test/org/apache/catalina/connector/TestMaxConnections.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/connector/TestMaxConnections.java?rev=1051291&r1=1051290&r2=1051291&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/connector/TestMaxConnections.java
(original)
+++ tomcat/trunk/test/org/apache/catalina/connector/TestMaxConnections.java Mon
Dec 20 21:01:37 2010
@@ -27,16 +27,21 @@ import org.apache.catalina.Context;
import org.apache.catalina.startup.SimpleHttpClient;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.coyote.http11.Http11NioProtocol;
+import org.apache.coyote.http11.Http11Protocol;
public class TestMaxConnections extends TomcatBaseTest{
- Tomcat tomcat = null;
static int soTimeout = 3000;
static int connectTimeout = 1000;
- public void test1() throws Exception {
- init();
- start();
+ @Override
+ public void setUp() throws Exception {
+ //do nothing
+ }
+
+ public void testBio() throws Exception {
+ init(Http11Protocol.class.getName());
ConnectThread[] t = new ConnectThread[10];
int passcount = 0;
int connectfail = 0;
@@ -52,54 +57,62 @@ public class TestMaxConnections extends
}
assertEquals("The number of successful requests should have been
5.",5, passcount);
assertEquals("The number of failed connects should have been 5.",5,
connectfail);
- stop();
}
+ public void testNio() throws Exception {
+ init(Http11NioProtocol.class.getName());
+ ConnectThread[] t = new ConnectThread[10];
+ int passcount = 0;
+ int connectfail = 0;
+ for (int i=0; i<t.length; i++) {
+ t[i] = new ConnectThread();
+ t[i].setName("ConnectThread["+i+"+]");
+ t[i].start();
+ }
+ for (int i=0; i<t.length; i++) {
+ t[i].join();
+ if (t[i].passed) passcount++;
+ if (t[i].connectfailed) connectfail++;
+ }
+
+ assertTrue("The number of successful requests should have been 4-5,
actual "+passcount,4==passcount || 5==passcount);
+
+ }
private class ConnectThread extends Thread {
public boolean passed = true;
public boolean connectfailed = false;
public void run() {
try {
- TestKeepAliveClient client = new TestKeepAliveClient();
+ TestClient client = new TestClient();
client.doHttp10Request();
}catch (Exception x) {
passed = false;
System.err.println(Thread.currentThread().getName()+"
Error:"+x.getMessage());
- connectfailed = "connect timed out".equals(x.getMessage());
+ connectfailed = "connect timed out".equals(x.getMessage()) ||
"Connection refused: connect".equals(x.getMessage());
}
}
}
- private boolean init;
- private synchronized void init() {
- if (init) return;
-
+ private synchronized void init(String protocol) throws Exception {
+ System.setProperty("tomcat.test.protocol", protocol);
+ super.setUp();
Tomcat tomcat = getTomcatInstance();
Context root = tomcat.addContext("", SimpleHttpClient.TEMP_DIR);
Tomcat.addServlet(root, "Simple", new SimpleServlet());
root.addServletMapping("/test", "Simple");
- tomcat.getConnector().setProperty("maxKeepAliveRequests", "5");
+ tomcat.getConnector().setProperty("maxKeepAliveRequests", "1");
tomcat.getConnector().setProperty("soTimeout", "20000");
tomcat.getConnector().setProperty("keepAliveTimeout", "50000");
tomcat.getConnector().setProperty("port", "8080");
tomcat.getConnector().setProperty("maxConnections", "4");
tomcat.getConnector().setProperty("acceptCount", "1");
- init = true;
- }
-
- private synchronized void start() throws Exception {
- tomcat = getTomcatInstance();
- init();
tomcat.start();
+ Thread.sleep(5000);
}
-
- private synchronized void stop() throws Exception {
- tomcat.stop();
- }
-
- private class TestKeepAliveClient extends SimpleHttpClient {
+
+ private class TestClient extends SimpleHttpClient {
private void doHttp10Request() throws Exception {
@@ -123,35 +136,6 @@ public class TestMaxConnections extends
assertTrue(passed);
}
- private void doHttp11Request() throws Exception {
- Tomcat tomcat = getTomcatInstance();
- init();
- tomcat.start();
- // Open connection
- connect();
-
- // Send request in two parts
- String[] request = new String[1];
- request[0] =
- "GET /test HTTP/1.1" + CRLF +
- "Host: localhost" + CRLF +
- "Connection: Keep-Alive" + CRLF+
- "Keep-Alive: 300"+ CRLF+ CRLF;
-
- setRequest(request);
-
- for (int i=0; i<5; i++) {
- processRequest(false); // blocks until response has been read
- assertTrue(getResponseLine()!=null &&
getResponseLine().trim().startsWith("HTTP/1.1 200"));
- }
- boolean passed = (this.readLine()==null);
- // Close the connection
- disconnect();
- reset();
- tomcat.stop();
- assertTrue(passed);
- }
-
@Override
public boolean isResponseBodyOK() {
return true;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]