ThreadPool Configuration in the Application Server

Introduction

Based on discussions and collective agreement, it is felt that the ThreadPool should really be a separate element in the server.xml instead of getting bundled in with the ORB element as it exists today in S1AS 7.0.

This document describes why this is useful to do and how this could be achieved.

ThreadPool configuration and DTD

If ThreadPool was made a separate element in the server.xml it would allow the user to configure more than one ThreadPools (if required) and associate these threadpools to other components of the Application Server (ORB, Connectors etc.). This would encourage code re-use as well as give the user controls to tune the Application Server based on the load in the system and in different sub-systems (ORB, Connectors etc.). Inherent advantages offered by this scheme: The DTD given below describes the ThreadPool configuration element. This element would be at the same level as the other components like http-service, iiop-service, web-container, ejb-container etc. in the S1AS 8.0 server.xml DTD (http://iaseng.red.iplanet.com/apollo/config/sun-server_8_0.dtd):
 

<!ELEMENT thread-pool-config (thread-pool+)>

<!--
     thread-pool-id                               This is an id for the work-queue e.g. "thread-pool-1", "thread-pool-2" etc
     min-thread-pool-size                     Minimum number of threads in the threadpool servicing requests in this queue.
                                                         These are created up front when this threadpool is instantiated
     max-thread-pool-size                    Maximum number of threads in the threadpool servicing requests in this queue
                                                         This is the upper bound on the no. of threads that exist in the threadpool.
     idle-thread-timeout-in-seconds      idle threads are removed from pool, after this time
     num-work-queues                         This denotes the total number of work queues that are serviced by this threadpool.
                                                          Default value would be 1
-->

<!ELEMENT thread-pool(EMPTY)>
<!ATTLIST thread-pool  thread-pool-id                          CDATA     #REQUIRED
                                       min-thread-pool-size                 CDATA     "0"
                                       max-thread-pool-size                CDATA     "200"
                                       idle-thread-timeout-in-seconds  CDATA     "120"
                                       num-work-queues                     CDATA     "1">

<!--  The ORB element would look like ...

        use-thread-pool-ids                        This would refer to the thread-pool-id(s) defined in the thread-pool sub-element of
                                                              thread-pool-config element in server.xml. These would be the threadpool(s) used by the
                                                              ORB. More than one thread-pool-id(s) could be specified by using commas to separate
                                                              the names e.g. "orb-thread-pool-1, orb-thread-pool-2"
-->

<!ELEMENT orb (property*)>
<!ATTLIST orb  message-fragment-size          CDATA     "1024"
               use-thread-pool-ids                           IDREFS         #REQUIRED
               max-connections                               CDATA         "1024"
               ....
               ...>

Essentially, thread-pool-config is a server wide element, that consists of atleast 1 or more thread-pool elements.

A ThreadPoolManagerImpl class could be used as a singleton instance, to create all the ThreadPools at server startup using the configuration parameters defined in the threadpool-config element of the server.xml. Any component can then get the threadpool instance by providing the threadpool-id to this singleton ThreadPoolManager instance. Using this threadpool instance a work queue serviced by this threadpool can be obtained. Work can be added to the queue and it will get processed by the threads of the threadpool.

EJB descriptors (or module descriptors - not sure if there is anything like this) could use the threadpool-ids defined in the server.xml to denote if the EJB (module) would want to use a dedicated threadpool. This could be done to avoid starvation. If nothing is specified or incorrect threadpool-id is specified in the bean descriptors, then the threadpool associated with the ORB will be used to service requests from that bean.
 
 

ThreadPoolManager SPI

This section defines the ThreadPoolManager SPI. This SPI will be defined in com.sun.corba.ee.spi....(the exact package name is TBD)

This interface will be implemented by the ThreadPoolManagerImpl class in App. Server PE 8.0. It will be responsible for returning an instance of the ThreadPool given a thread-pool-id, from any component that wants to use a ThreadPool. In addition, ThreadPoolManagerImpl class will be responsible for creating all the threadpools (and their queues) at server startup time. This is done using the config bean that reads the thread-pool-config element in server.xml. ThreadPoolManager instance would be a singleton instance in the App. Server process.
 

public interface ThreadPoolManager {

    /**
    * This method will return an instance of the threadpool given a threadpoolId,
    * that can be used by any component in the app. server.
    */
    public ThreadPool getThreadPool(String threadpoolId);

    /**
    * This method will return an instance of the threadpool given a numeric threadpoolId.
    * This method will be used by the ORB to support the functionality of
    * dedicated threadpool for EJB beans
    */
    public ThreadPool getThreadPool(int numericIdForThreadpool);

    /**
    * This method is used to return the numeric id of the threadpool, given a String
    * threadpoolId. This is used by the POA interceptors to add the numeric threadpool
    * Id, as a tagged component in the IOR. This is used to provide the functionality of
    * dedicated threadpool for EJB beans
    */
    public int  getNumericId(String threadpoolId);

    /**
    * Return a String Id for a numericId of a threadpool managed by the threadpool
    * manager
    */
    public String getStringId(int numericIdForThreadpool);

    /**
    * Returns the first instance of ThreadPool in the ThreadPoolManager
    */
    public ThreadPool getDefaultThreadPool();

}

An implementation of this SPI will also exist in the ORB that ships with J2SE, so that the ORB code that uses these API does not change for J2SE.
 

ThreadPool SPI

This section defines the ThreadPool SPI. This SPI will be defined in com.sun.corba.ee.spi....(the exact package name is TBD)

The ORB already has plans for having an interface like that as part of the work being done on the design of the ORB transport. I am adding more APIs to the designed interface for this done by Harold Carr.

public interface ThreadPool {

    /**
    * This method will return any instance of the WorkQueue. If the ThreadPool
    * instance only services one WorkQueue then that WorkQueue instance will
    * be returned. If there are more than one WorkQueues serviced by this
    * ThreadPool, then this method would return a WorkQueue based on the
    * implementation of the class that implements this interface. For PE 8.0 we
    * would return a WorkQueue in a roundrobin fashion everytime this method
    * is called. In the future we could allow pluggability of  Policy objects for this.
    */
    public WorkQueue getAnyWorkQueue();

    /**
    * This method will return an instance of the of the WorkQueue given a queueId.
    * This will be useful in situations where there are more than one WorkQueues
    * managed by the ThreadPool and the user of the ThreadPool wants to always use
    * the same WorkQueue for doing the Work.
    * If the number of WorkQueues in the ThreadPool are 10, then queueIds will go
    * from 0-9
    */
    public WorkQueue getWorkQueue(int queueId);

    /**
    * This method will return the number of WorkQueues serviced by the threadpool.
    */
    public int numberOfWorkQueues();

    /**
    * This method will return the minimum number of threads maintained by the threadpool.
    */
    public int minimumNumberOfThreads();

    /**
    * This method will return the maximum number of threads in the threadpool at any
    * point in time, for the life of the threadpool
    */
    public int maximumNumberOfThreads();

    /**
    * This method will return the time in milliseconds when idle threads in the threadpool are
    * removed.
    */
    public long idleTimeoutForThreads();

    /**
    * This method will return the current number of threads in the threadpool. This method
    * returns a value which is not synchronized.
    */
    public int currentNumberOfThreads();

    /**
    * This method will return the number of available threads in the threadpool which are
     * waiting for work. This method returns a value which is not synchronized.
    */
    public int numberOfAvailableThreads();

    /**
    * This method will return the number of busy threads in the threadpool
    * This method returns a value which is not synchronized.
    */
    public int numberOfBusyThreads();

    /**
    * This method returns the number of Work items processed by the threadpool
    */
    public long currentProcessedCount();

    /**
    * This method will return the name of the threadpool.
    */
    public String getName();

}
 

WorkQueue SPI

This section defines the WorkQueue SPI. This SPI will be defined in com.sun.corba.ee.spi....(the exact package name is TBD)

The ORB already has plans for having an interface like that as part of the work being done on the design of the ORB transport by Harold Carr. The following has been borrowed from that design

public interface WorkQueue {

    /**
    * This method is used to add work to the WorkQueue
    */
    public void addWork(Work aWorkItem);

    /**
    * This method will return the name of the WorkQueue.
    */
    public String getName();

    /**
    * Returns the total number of Work items added to the Queue.
    */
    public long totalWorkItemsAdded();

    /**
    * Returns the total number of Work items in the Queue to be processed.
    */
    public int workItemsInQueue();

}
 

Work SPI

This section defines the Work SPI. This SPI will be defined in com.sun.corba.ee.spi....(the exact package name is TBD)

The ORB already has plans for having an interface like that as part of the work being done on the design of the ORB transport by Harold Carr. The following has been borrowed from that design

public interface Work {

    public void doWork();

    public String getName();

}