Revision: 8985
Author: brainslog
Date: Fri Dec 11 10:13:41 2009
Log: Fixes Issue 1075 (Improve thread management in JDiameter).
http://code.google.com/p/mobicents/source/detail?r=8985

Modified:
/trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerTableImpl.java /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Parameters.java /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/XMLConfiguration.java /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/XMLConfiguration.java /trunk/servers/diameter/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-client.xsd /trunk/servers/diameter/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-server.xsd /trunk/servers/diameter/core/mux/sar-jboss-4/src/main/resources/config/jdiameter-config.xml /trunk/servers/diameter/core/mux/sar-jboss-5/src/main/resources/config/jdiameter-config.xml

=======================================
--- /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerTableImpl.java Thu Oct 8 02:46:37 2009 +++ /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/controller/PeerTableImpl.java Fri Dec 11 10:13:41 2009
@@ -25,6 +25,11 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;

 import org.jdiameter.api.Avp;
 import org.jdiameter.api.AvpDataException;
@@ -52,7 +57,27 @@

 public class PeerTableImpl implements IPeerTable {

-  protected Logger logger = LoggerFactory.getLogger(PeerTableImpl.class);
+ protected static final Logger logger = LoggerFactory.getLogger(PeerTableImpl.class);
+
+  /**
+ * determines core pool size, those threads are always there, so if there is no traffic stack wont take much time to act.
+   */
+  private static final int _THREAD_POOL_CORE_SIZE = 1;
+  /**
+   * determines in seconds keep alive time for thread in pool.
+   */
+  private static final int _THREAD_POOL_KEEP_ALIVE_TIME = 60;
+  /**
+   * determines how many thread pool can have.
+   */
+  protected int maximumThreadPoolSize = 5;
+  /**
+   * determines thread priority for executor.
+   */
+  protected int threadPoolPriority = Thread.NORM_PRIORITY;
+  protected ThreadFactory threadFactory;
+
+
   // Peer table
protected ConcurrentHashMap<URI,Peer> peerTable = new ConcurrentHashMap<URI,Peer>();
   protected boolean isStarted;
@@ -76,7 +101,18 @@
     this.router = router;
     this.metaData = metaData;
this.stopTimeOut = globalConfig.getLongValue(StopTimeOut.ordinal(), (Long) StopTimeOut.defValue());
-    this.peerTaskExecutor = Executors.newCachedThreadPool();
+ Configuration[] threadPoolConf = globalConfig.getChildren(Parameters.ThreadPool.ordinal());
+    if(threadPoolConf!=null && threadPoolConf.length>0)
+    {
+       Configuration tpc = threadPoolConf[0];
+ this.maximumThreadPoolSize = tpc.getIntValue(Parameters.ThreadPoolSize.ordinal(), (Integer)Parameters.ThreadPoolSize.defValue()); + this.threadPoolPriority = tpc.getIntValue(Parameters.ThreadPoolPriority.ordinal(), (Integer)Parameters.ThreadPoolPriority.defValue());
+    }
+
+ this.threadFactory = new PeerTableThreadFactory(this.threadPoolPriority);
+    //this.peerTaskExecutor = Executors.newCachedThreadPool();
+ this.peerTaskExecutor = new ThreadPoolExecutor(_THREAD_POOL_CORE_SIZE, this.maximumThreadPoolSize, _THREAD_POOL_KEEP_ALIVE_TIME, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), this.threadFactory);
+
Configuration[] peers = globalConfig.getChildren( Parameters.PeerTable.ordinal() );
     if (peers != null && peers.length > 0) {
       for (Configuration peerConfig : peers) {
@@ -280,4 +316,28 @@
   public <T> T unwrap(Class<T> aClass) throws InternalException {
     return null;
   }
-}
+
+  protected class PeerTableThreadFactory implements ThreadFactory {
+
+           public final AtomicLong sequence = new AtomicLong(0);
+           private int priority = Thread.NORM_PRIORITY;
+ private ThreadGroup factoryThreadGroup = new ThreadGroup("JDiameterThreadGroup[" + sequence.incrementAndGet() + "]");
+
+
+
+           public PeerTableThreadFactory(int priority) {
+                       super();
+                       this.priority = priority;
+               }
+
+
+
+               public Thread newThread(Runnable r) {
+               Thread t = new Thread(this.factoryThreadGroup, r);
+               t.setPriority(this.priority);
+               // ??
+               //t.start();
+               return t;
+           }
+  }
+}
=======================================
--- /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Parameters.java Wed Oct 14 05:38:38 2009 +++ /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/Parameters.java Fri Dec 11 10:13:41 2009
@@ -258,6 +258,18 @@
      */
public static final Parameters SecurityRef = new Parameters("SecurityRef",String.class);

+    /**
+    * XML entry for thread pool
+    */
+ public static final Parameters ThreadPool = new Parameters("ThreadPool",Object.class);
+    /**
+    * Thread pool max size
+    */
+ public static final Parameters ThreadPoolSize = new Parameters("ThreadPoolSize",Integer.class,10);
+    /**
+    * Thread pool max size
+    */
+ public static final Parameters ThreadPoolPriority = new Parameters("ThreadPoolPriority",Integer.class,5);
     /**
      * Return all parameters as iterator
      * @return all parameters as iterator
=======================================
--- /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/XMLConfiguration.java Mon Aug 3 17:25:21 2009 +++ /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/helpers/XMLConfiguration.java Fri Dec 11 10:13:41 2009
@@ -10,9 +10,12 @@
 package org.jdiameter.client.impl.helpers;

 import org.jdiameter.api.Configuration;
+
 import static org.jdiameter.client.impl.helpers.Parameters.*;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;

@@ -179,21 +182,48 @@
         NodeList c = node.getChildNodes();
         for (int i = 0; i < c.getLength(); i++) {
             String nodeName = c.item(i).getNodeName();
- if (nodeName.equals("UseUriAsFqdn")) add(UseUriAsFqdn, Boolean.valueOf(getValue(c.item(i)))); - if (nodeName.equals("QueueSize")) add(QueueSize, getIntValue(c.item(i))); - if (nodeName.equals("MessageTimeOut")) add(MessageTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("StopTimeOut")) add(StopTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("CeaTimeOut")) add(CeaTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("IacTimeOut")) add(IacTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("DwaTimeOut")) add(DwaTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("DpaTimeOut")) add(DpaTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("RecTimeOut")) add(RecTimeOut, getLongValue(c.item(i))); + if (nodeName.equals("UseUriAsFqdn")) { add(UseUriAsFqdn, Boolean.valueOf(getValue(c.item(i)))); } + else if (nodeName.equals("QueueSize")) { add(QueueSize, getIntValue(c.item(i))); } + else if (nodeName.equals("MessageTimeOut")) { add(MessageTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("StopTimeOut")) { add(StopTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("CeaTimeOut")) { add(CeaTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("IacTimeOut")) { add(IacTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("DwaTimeOut")) { add(DwaTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("DpaTimeOut")) { add(DpaTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("RecTimeOut")) { add(RecTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("ThreadPool")) { addThreadPool(c.item(i)); }
+            else
             appendOtherParameter(c.item(i));
         }
-    }
-
+    }
     protected void appendOtherParameter(Node node) {
     }
+
+       protected void addThreadPool(Node item) {
+
+ AppConfiguration threadPoolConfiguration = EmptyConfiguration.getInstance();
+               NamedNodeMap attributes = item.getAttributes();
+
+               for (int index = 0; index < attributes.getLength(); index++) {
+                       Node n = attributes.item(index);
+
+                       int v = Integer.parseInt(n.getNodeValue());
+                       if (n.getNodeName().equals("size")) {
+                               threadPoolConfiguration.add(ThreadPoolSize, v);
+                       } else if (n.getNodeName().equals("priority")) {
+                               threadPoolConfiguration.add(ThreadPoolPriority, 
v);
+                       } else {
+ //log.error("Unkonwn attribute on " + item.getNodeName() + ", attribute name: " + n.getNodeName());
+                       }
+               }
+ if (!threadPoolConfiguration.isAttributeExist(ThreadPoolSize.ordinal())) {
+                       threadPoolConfiguration.add(ThreadPoolSize, 
ThreadPoolSize.defValue());
+               }
+ if (!threadPoolConfiguration.isAttributeExist(ThreadPoolPriority.ordinal())) { + threadPoolConfiguration.add(ThreadPoolPriority, ThreadPoolPriority.defValue());
+               }
+               this.add(ThreadPool, threadPoolConfiguration);
+       }

     protected void addSecurity(Node node) {
         NodeList c = node.getChildNodes();
=======================================
--- /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/XMLConfiguration.java Fri Jun 26 01:48:28 2009 +++ /trunk/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/helpers/XMLConfiguration.java Fri Dec 11 10:13:41 2009
@@ -14,6 +14,7 @@
 import static org.jdiameter.server.impl.helpers.Parameters.*;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;

@@ -162,19 +163,47 @@
         NodeList c = node.getChildNodes();
         for (int i = 0; i < c.getLength(); i++) {
             String nodeName = c.item(i).getNodeName();
- if (nodeName.equals("UseUriAsFqdn")) add(UseUriAsFqdn, Boolean.valueOf(getValue(c.item(i)))); - if (nodeName.equals("QueueSize")) add(QueueSize, getIntValue(c.item(i))); - if (nodeName.equals("MessageTimeOut")) add(MessageTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("StopTimeOut")) add(StopTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("CeaTimeOut")) add(CeaTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("IacTimeOut")) add(IacTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("DwaTimeOut")) add(DwaTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("DpaTimeOut")) add(DpaTimeOut, getLongValue(c.item(i))); - if (nodeName.equals("RecTimeOut")) add(RecTimeOut, getLongValue(c.item(i)));
-            appendOtherParameter(c.item(i));
+ if (nodeName.equals("UseUriAsFqdn")) { add(UseUriAsFqdn, Boolean.valueOf(getValue(c.item(i)))); } + else if (nodeName.equals("QueueSize")) { add(QueueSize, getIntValue(c.item(i))); } + else if (nodeName.equals("MessageTimeOut")) { add(MessageTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("StopTimeOut")) { add(StopTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("CeaTimeOut")) { add(CeaTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("IacTimeOut")) { add(IacTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("DwaTimeOut")) { add(DwaTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("DpaTimeOut")) { add(DpaTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("RecTimeOut")) { add(RecTimeOut, getLongValue(c.item(i))); } + else if (nodeName.equals("ThreadPool")) { addThreadPool(c.item(i)); }
+            else
+            {    appendOtherParameter(c.item(i)); }
         }
     }

+       protected void addThreadPool(Node item) {
+
+ AppConfiguration threadPoolConfiguration = EmptyConfiguration.getInstance();
+               NamedNodeMap attributes = item.getAttributes();
+
+               for (int index = 0; index < attributes.getLength(); index++) {
+                       Node n = attributes.item(index);
+
+                       int v = Integer.parseInt(n.getNodeValue());
+                       if (n.getNodeName().equals("size")) {
+                               threadPoolConfiguration.add(ThreadPoolSize, v);
+                       } else if (n.getNodeName().equals("priority")) {
+                               threadPoolConfiguration.add(ThreadPoolPriority, 
v);
+                       } else {
+ //log.error("Unkonwn attribute on " + item.getNodeName() + ", attribute name: " + n.getNodeName());
+                       }
+               }
+ if (!threadPoolConfiguration.isAttributeExist(ThreadPoolSize.ordinal())) {
+                       threadPoolConfiguration.add(ThreadPoolSize, 
ThreadPoolSize.defValue());
+               }
+ if (!threadPoolConfiguration.isAttributeExist(ThreadPoolPriority.ordinal())) { + threadPoolConfiguration.add(ThreadPoolPriority, ThreadPoolPriority.defValue());
+               }
+               this.add(ThreadPool, threadPoolConfiguration);
+
+       }
     protected void addNetwork(Node node) {
         NodeList c = node.getChildNodes();
         for (int i = 0; i < c.getLength(); i++) {
=======================================
--- /trunk/servers/diameter/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-client.xsd Fri Jun 26 01:48:28 2009 +++ /trunk/servers/diameter/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-client.xsd Fri Dec 11 10:13:41 2009
@@ -214,6 +214,15 @@
<xsi:attribute name="value" type="xsi:long" use="required"/>
                </xsi:complexType>
             </xsi:element>
+            <xsi:element name="ThreadPool" minOccurs="1" maxOccurs="1">
+                <xsi:annotation>
+ <xsi:documentation>Determines thread pool configuration.</xsi:documentation>
+                </xsi:annotation>
+               <xsi:complexType>
+ <xsi:attribute name="priority" type="xsi:string" default="5"/> + <xsi:attribute name="size" type="xsi:integer" default="16"/>
+               </xsi:complexType>
+            </xsi:element>
         </xsi:sequence>
     </xsi:complexType>

=======================================
--- /trunk/servers/diameter/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-server.xsd Fri Jun 26 01:48:28 2009 +++ /trunk/servers/diameter/core/jdiameter/impl/src/main/resources/META-INF/jdiameter-server.xsd Fri Dec 11 10:13:41 2009
@@ -272,6 +272,15 @@
<xsi:attribute name="value" type="xsi:long" use="required"/>
                </xsi:complexType>
             </xsi:element>
+            <xsi:element name="ThreadPool" minOccurs="1" maxOccurs="1">
+                <xsi:annotation>
+ <xsi:documentation>Determines thread pool configuration.</xsi:documentation>
+                </xsi:annotation>
+               <xsi:complexType>
+ <xsi:attribute name="priority" type="xsi:string" default="5"/> + <xsi:attribute name="size" type="xsi:integer" default="16"/>
+               </xsi:complexType>
+            </xsi:element>
         </xsi:sequence>
     </xsi:complexType>

=======================================
--- /trunk/servers/diameter/core/mux/sar-jboss-4/src/main/resources/config/jdiameter-config.xml Thu Oct 15 08:37:24 2009 +++ /trunk/servers/diameter/core/mux/sar-jboss-4/src/main/resources/config/jdiameter-config.xml Fri Dec 11 10:13:41 2009
@@ -35,6 +35,7 @@
     <DwaTimeOut value="10000" />
     <DpaTimeOut value="5000" />
     <RecTimeOut value="10000" />
+    <ThreadPool size="10" priority="5"/>
   </Parameters>

   <Network>
=======================================
--- /trunk/servers/diameter/core/mux/sar-jboss-5/src/main/resources/config/jdiameter-config.xml Thu Oct 15 08:37:24 2009 +++ /trunk/servers/diameter/core/mux/sar-jboss-5/src/main/resources/config/jdiameter-config.xml Fri Dec 11 10:13:41 2009
@@ -35,7 +35,8 @@
     <DwaTimeOut value="10000" />
     <DpaTimeOut value="5000" />
     <RecTimeOut value="10000" />
-  </Parameters>
+    <ThreadPool size="10" priority="5"/>
+    </Parameters>

   <Network>
     <Peers>

Reply via email to