Hi,
If we just fixed only Controller#initializeDefaults(), it is not enough.
Actually when I ran AsyncHTTPResponseTest on 4 CPUs after I fixed Controller#initializeDefaults() experimentally, the test didn't ended and was blocked infinitely because of lack of thread's size.
So, we should also consider that any modules and users can call Controller#setThreadPool() like http's SelectorThread#initController().
I attached the proposed patch.
Index: com/sun/grizzly/Controller.java
===================================================================
--- com/sun/grizzly/Controller.java (revision 3298)
+++ com/sun/grizzly/Controller.java (working copy)
@@ -49,6 +49,8 @@
import com.sun.grizzly.util.SupportStateHolder;
import com.sun.grizzly.util.WorkerThreadFactory;
import com.sun.grizzly.util.WorkerThreadImpl;
+import com.sun.grizzly.util.FixedThreadPool;
+
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
@@ -151,9 +153,9 @@
UDP, TCP, TLS, CUSTOM
}
/**
- * Maximum number of {_at_link Threads} created by a {_at_link DefaultThreadPool}
+ * Required number of threads created by a {_at_link DefaultThreadPool}
*/
- private int maxThreads = DefaultThreadPool.DEFAULT_MAX_THREAD_COUNT;
+ private int requiredThreadsCount = DefaultThreadPool.DEFAULT_MIN_THREAD_COUNT;
/**
* A cached list of Context. Context are by default stateless.
*/
@@ -289,11 +291,8 @@
autoConfigureCore();
if (threadPool == null) {
threadPool = new DefaultThreadPool();
- }
- if (threadPool instanceof ThreadPoolExecutor){
- ((ThreadPoolExecutor)threadPool).setMaximumPoolSize(maxThreads);
- ((ThreadPoolExecutor)threadPool).setCorePoolSize(maxThreads);
- }
+ }
+ ensureAppropriatePoolSize( threadPool );
if (instanceHandler == null) {
instanceHandler = new DefaultProtocolChainInstanceHandler();
}
@@ -307,17 +306,35 @@
controllers.add(this);
}
+ private void ensureAppropriatePoolSize( ExecutorService threadPool ) {
+ if( threadPool == null )
+ return;
+ if( threadPool instanceof FixedThreadPool ) {
+ FixedThreadPool fixedThreadPool = (FixedThreadPool)threadPool;
+ if( fixedThreadPool.getMaximumPoolSize() < requiredThreadsCount )
+ fixedThreadPool.setMaximumPoolSize( requiredThreadsCount );
+ } else if( threadPool instanceof ThreadPoolExecutor ) {
+ ThreadPoolExecutor jdkThreadPool = (ThreadPoolExecutor)threadPool;
+ if( jdkThreadPool.getCorePoolSize() < requiredThreadsCount ) {
+ if( jdkThreadPool.getMaximumPoolSize() < requiredThreadsCount )
+ jdkThreadPool.setMaximumPoolSize( requiredThreadsCount );
+ jdkThreadPool.setCorePoolSize( requiredThreadsCount );
+ }
+ }
+ }
+
/**
* Auto-configure the number of {_at_link ReaderThread} based on the core
* processor.
*/
private void autoConfigureCore(){
readThreadsCount = Runtime.getRuntime().availableProcessors();
- maxThreads = maxThreads * readThreadsCount;
+ if( readThreadsCount > 0 )
+ requiredThreadsCount = DefaultThreadPool.DEFAULT_MIN_THREAD_COUNT * readThreadsCount;
if (logger.isLoggable(Level.FINE)){
logger.fine("Controller auto-configured with 2 ReadController " +
"based on underlying cores/processors, with a Thread Pool " +
- "of maximum size " + maxThreads);
+ "of required size " + requiredThreadsCount );
}
}
@@ -594,6 +611,7 @@
* Set the {_at_link ExecutorService} (Thread Pool).
*/
public void setThreadPool(ExecutorService threadPool) {
+ ensureAppropriatePoolSize( threadPool );
this.threadPool = threadPool;
}
@@ -609,6 +627,9 @@
*/
public void setReadThreadsCount(int readThreadsCount) {
this.readThreadsCount = readThreadsCount;
+ if( readThreadsCount > 0 )
+ requiredThreadsCount = DefaultThreadPool.DEFAULT_MIN_THREAD_COUNT * readThreadsCount;
+ ensureAppropriatePoolSize( threadPool );
}
/**
--
Bongjae Chang
----- Original Message -----
From: Bongjae Chang
To: dev_at_grizzly.dev.java.net
Sent: Friday, June 05, 2009 5:59 PM
Subject: Most of test case failed on 4CPUs
Hi,
Today, I ran all test cases on 4CPUs, but most of them failed.
When I debugged, the problem was thread pool size again. :(
See the following source.
---
In Controller.java
private void initializeDefaults() {
autoConfigureCore();
if( threadPool == null ) {
threadPool = new DefaultThreadPool();
}
if(threadPool instanceof ThreadPoolExecutor) {
((ThreadPoolExecutor)threadPool).setMaximumPoolSize(maxThreads);
((ThreadPoolExecutor)threadPool).setCorePoolSize(maxThreads);
}
...
}
---
Current DefaultThreadPool is not instance of ThreadPoolExecutor which is based on JDK but FixedThreadPool!
I think that we need to fix above code or the threadPool should be created by appropriate max size like maxThreads.
Thanks.
--
Bongjae Chang