dev@grizzly.java.net

Re: Most of test case failed on 4CPUs

From: Bongjae Chang <carryel_at_korea.com>
Date: Fri, 5 Jun 2009 20:10:26 +0900

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