You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2007/03/21 19:00:40 UTC

svn commit: r520968 - in /tomcat/tc6.0.x/trunk: conf/ java/org/apache/catalina/ java/org/apache/catalina/core/ java/org/apache/catalina/startup/ java/org/apache/tomcat/util/net/

Author: fhanik
Date: Wed Mar 21 11:00:39 2007
New Revision: 520968

URL: http://svn.apache.org/viewvc?view=rev&rev=520968
Log:
Added in the Executor skeleton. the executor gets created in the service, so that the connectors can reference it.
Feel free to hack away on improvements or yell at me if this is completely not what was intended and I will pull it out


Added:
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/Executor.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java
Modified:
    tomcat/tc6.0.x/trunk/conf/server.xml
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/Service.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardService.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/Catalina.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ConnectorCreateRule.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/EngineRuleSet.java
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/SetAllPropertiesRule.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java

Modified: tomcat/tc6.0.x/trunk/conf/server.xml
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/conf/server.xml?view=diff&rev=520968&r1=520967&r2=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/conf/server.xml (original)
+++ tomcat/tc6.0.x/trunk/conf/server.xml Wed Mar 21 11:00:39 2007
@@ -32,7 +32,13 @@
        Documentation at /docs/config/service.html
    -->
   <Service name="Catalina">
-
+  
+    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
+    <!--
+    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="1000" minSpareThreads="4"/>
+    -->
+    
+    
     <!-- A "Connector" represents an endpoint by which requests are received
          and responses are returned. Documentation at :
          Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
@@ -41,9 +47,15 @@
          Define a non-SSL HTTP/1.1 Connector on port 8080
     -->
     <Connector port="8080" protocol="HTTP/1.1" 
-               maxThreads="150" connectionTimeout="20000" 
+               connectionTimeout="20000" 
+               redirectPort="8443" />
+    <!-- A "Connector" using the shared thread pool-->
+    <!--
+    <Connector executor="tomcatThreadPool"
+               port="8080" protocol="HTTP/1.1" 
+               connectionTimeout="20000" 
                redirectPort="8443" />
-
+    -->           
     <!-- Define a SSL HTTP/1.1 Connector on port 8443
          This connector uses the JSSE configuration, when using APR, the 
          connector should be using the OpenSSL style configuration

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Executor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/Executor.java?view=auto&rev=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/Executor.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/Executor.java Wed Mar 21 11:00:39 2007
@@ -0,0 +1,7 @@
+package org.apache.catalina;
+
+
+
+public interface Executor extends java.util.concurrent.Executor, Lifecycle {
+    public String getName();
+}
\ No newline at end of file

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Service.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/Service.java?view=diff&rev=520968&r1=520967&r2=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/Service.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/Service.java Wed Mar 21 11:00:39 2007
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,6 @@
 
 import org.apache.catalina.connector.Connector;
 
-
 /**
  * A <strong>Service</strong> is a group of one or more
  * <strong>Connectors</strong> that share a single <strong>Container</strong>
@@ -37,7 +36,6 @@
 
 public interface Service {
 
-
     // ------------------------------------------------------------- Properties
 
 
@@ -47,7 +45,6 @@
      */
     public Container getContainer();
 
-
     /**
      * Set the <code>Container</code> that handles requests for all
      * <code>Connectors</code> associated with this Service.
@@ -56,7 +53,6 @@
      */
     public void setContainer(Container container);
 
-
     /**
      * Return descriptive information about this Service implementation and
      * the corresponding version number, in the format
@@ -64,13 +60,11 @@
      */
     public String getInfo();
 
-
     /**
      * Return the name of this Service.
      */
     public String getName();
 
-
     /**
      * Set the name of this Service.
      *
@@ -78,13 +72,11 @@
      */
     public void setName(String name);
 
-
     /**
      * Return the <code>Server</code> with which we are associated (if any).
      */
     public Server getServer();
 
-
     /**
      * Set the <code>Server</code> with which we are associated (if any).
      *
@@ -92,7 +84,6 @@
      */
     public void setServer(Server server);
 
-    
     // --------------------------------------------------------- Public Methods
 
 
@@ -104,13 +95,11 @@
      */
     public void addConnector(Connector connector);
 
-
     /**
      * Find and return the set of Connectors associated with this Service.
      */
     public Connector[] findConnectors();
 
-
     /**
      * Remove the specified Connector from the set associated from this
      * Service.  The removed Connector will also be disassociated from our
@@ -126,7 +115,31 @@
      *
      * @exception LifecycleException If this server was already initialized.
      */
-    public void initialize()
-    throws LifecycleException;
+    public void initialize() throws LifecycleException;
+
+    /**
+     * Adds a named executor to the service
+     * @param ex Executor
+     */
+    public void addExecutor(Executor ex);
+
+    /**
+     * Retrieves all executors
+     * @return Executor[]
+     */
+    public Executor[] findExecutors();
+
+    /**
+     * Retrieves executor by name, null if not found
+     * @param name String
+     * @return Executor
+     */
+    public Executor getExecutor(String name);
+    
+    /**
+     * Removes an executor from the service
+     * @param ex Executor
+     */
+    public void removeExecutor(Executor ex);
 
 }

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardService.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardService.java?view=diff&rev=520968&r1=520967&r2=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardService.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardService.java Wed Mar 21 11:00:39 2007
@@ -38,6 +38,8 @@
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.modeler.Registry;
+import java.util.ArrayList;
+import org.apache.catalina.Executor;
 
 
 /**
@@ -103,7 +105,11 @@
      * The set of Connectors associated with this Service.
      */
     protected Connector connectors[] = new Connector[0];
-
+    
+    /**
+     * 
+     */
+    protected ArrayList<Executor> executors = new ArrayList<Executor>();
 
     /**
      * The Container associated with this Service. (In the case of the
@@ -413,6 +419,68 @@
         lifecycle.removeLifecycleListener(listener);
 
     }
+    
+    /**
+     * Adds a named executor to the service
+     * @param ex Executor
+     */
+    public void addExecutor(Executor ex) {
+        synchronized (executors) {
+            if (!executors.contains(ex)) {
+                executors.add(ex);
+                if (started)
+                    try {
+                        ex.start();
+                    } catch (LifecycleException x) {
+                        log.error("Executor.start", x);
+                    }
+            }
+        }
+    }
+
+    /**
+     * Retrieves all executors
+     * @return Executor[]
+     */
+    public Executor[] findExecutors() {
+        synchronized (executors) {
+            Executor[] arr = new Executor[executors.size()];
+            executors.toArray(arr);
+            return arr;
+        }
+    }
+
+    /**
+     * Retrieves executor by name, null if not found
+     * @param name String
+     * @return Executor
+     */
+    public Executor getExecutor(String name) {
+        synchronized (executors) {
+            for (int i = 0; i < executors.size(); i++) {
+                if (name.equals(executors.get(i).getName()))
+                    return executors.get(i);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes an executor from the service
+     * @param ex Executor
+     */
+    public void removeExecutor(Executor ex) {
+        synchronized (executors) {
+            if ( executors.remove(ex) && started ) {
+                try {
+                    ex.stop();
+                } catch (LifecycleException e) {
+                    log.error("Executor.stop", e);
+                }
+            }
+        }
+    }
+
 
 
     /**
@@ -455,6 +523,12 @@
             for (int i = 0; i < connectors.length; i++) {
                 if (connectors[i] instanceof Lifecycle)
                     ((Lifecycle) connectors[i]).start();
+            }
+        }
+        
+        synchronized (executors) {
+            for ( int i=0; i<executors.size(); i++ ) {
+                executors.get(i).start();
             }
         }
 

Added: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java?view=auto&rev=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardThreadExecutor.java Wed Mar 21 11:00:39 2007
@@ -0,0 +1,204 @@
+package org.apache.catalina.core;
+
+import java.util.Collection;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.catalina.Executor;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.util.LifecycleSupport;
+
+public class StandardThreadExecutor implements Executor {
+    
+    // ---------------------------------------------- Properties
+    protected int threadPriority = Thread.NORM_PRIORITY;
+
+    protected boolean daemon = true;
+    
+    protected String namePrefix = "tomcat-exec-";
+    
+    protected int maxThreads = 200;
+    
+    protected int minSpareThreads = 25;
+    
+    protected int maxIdleTime = 60000;
+    
+    protected ThreadPoolExecutor executor = null;
+    
+    protected String name;
+    
+    private LifecycleSupport lifecycle = new LifecycleSupport(this);
+    // ---------------------------------------------- Constructors
+    public StandardThreadExecutor() {
+        //empty constructor for the digester
+    }
+    
+
+    
+    // ---------------------------------------------- Public Methods
+    public void start() throws LifecycleException {
+        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
+        TaskQueue taskqueue = new TaskQueue();
+        TaskThreadFactory tf = new TaskThreadFactory(namePrefix);
+        lifecycle.fireLifecycleEvent(START_EVENT, null);
+        executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS,taskqueue, tf);
+        taskqueue.setParent( (ThreadPoolExecutor) executor);
+        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
+    }
+    
+    public void stop() throws LifecycleException{
+        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
+        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
+        if ( executor != null ) executor.shutdown();
+        executor = null;
+        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
+    }
+    
+    public void execute(Runnable command) {
+        if ( executor != null ) executor.execute(command);
+        else throw new IllegalStateException("StandardThreadPool not started.");
+    }
+
+    public int getThreadPriority() {
+        return threadPriority;
+    }
+
+    public boolean isDaemon() {
+
+        return daemon;
+    }
+
+    public String getNamePrefix() {
+        return namePrefix;
+    }
+
+    public int getMaxIdleTime() {
+        return maxIdleTime;
+    }
+
+    public int getMaxThreads() {
+        return maxThreads;
+    }
+
+    public int getMinSpareThreads() {
+        return minSpareThreads;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setThreadPriority(int threadPriority) {
+        this.threadPriority = threadPriority;
+    }
+
+    public void setDaemon(boolean daemon) {
+        this.daemon = daemon;
+    }
+
+    public void setNamePrefix(String namePrefix) {
+        this.namePrefix = namePrefix;
+    }
+
+    public void setMaxIdleTime(int maxIdleTime) {
+        this.maxIdleTime = maxIdleTime;
+    }
+
+    public void setMaxThreads(int maxThreads) {
+        this.maxThreads = maxThreads;
+    }
+
+    public void setMinSpareThreads(int minSpareThreads) {
+        this.minSpareThreads = minSpareThreads;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    /**
+     * Add a LifecycleEvent listener to this component.
+     *
+     * @param listener The listener to add
+     */
+    public void addLifecycleListener(LifecycleListener listener) {
+        lifecycle.addLifecycleListener(listener);
+    }
+
+
+    /**
+     * Get the lifecycle listeners associated with this lifecycle. If this 
+     * Lifecycle has no listeners registered, a zero-length array is returned.
+     */
+    public LifecycleListener[] findLifecycleListeners() {
+        return lifecycle.findLifecycleListeners();
+    }
+
+
+    /**
+     * Remove a LifecycleEvent listener from this component.
+     *
+     * @param listener The listener to remove
+     */
+    public void removeLifecycleListener(LifecycleListener listener) {
+        lifecycle.removeLifecycleListener(listener);
+    }
+
+
+    
+
+
+    // ---------------------------------------------- TaskQueue Inner Class
+    class TaskQueue extends LinkedBlockingQueue<Runnable> {
+        ThreadPoolExecutor parent = null;
+
+        public TaskQueue() {
+            super();
+        }
+
+        public TaskQueue(int initialCapacity) {
+            super(initialCapacity);
+        }
+
+        public TaskQueue(Collection<? extends Runnable> c) {
+            super(c);
+        }
+
+        public void setParent(ThreadPoolExecutor tp) {
+            parent = tp;
+        }
+
+        public boolean offer(Runnable o) {
+            if (parent != null && parent.getPoolSize() < parent.getMaximumPoolSize())
+                return false; //force creation of new threads
+            else
+                return super.offer(o);
+        }
+    }
+
+    // ---------------------------------------------- ThreadFactory Inner Class
+    class TaskThreadFactory implements ThreadFactory {
+        final ThreadGroup group;
+        final AtomicInteger threadNumber = new AtomicInteger(1);
+        final String namePrefix;
+
+        TaskThreadFactory(String namePrefix) {
+            SecurityManager s = System.getSecurityManager();
+            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
+            this.namePrefix = namePrefix;
+        }
+
+        public Thread newThread(Runnable r) {
+            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement());
+            t.setDaemon(daemon);
+            t.setPriority(getThreadPriority());
+            return t;
+        }
+    }
+
+
+}
\ No newline at end of file

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/Catalina.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/Catalina.java?view=diff&rev=520968&r1=520967&r2=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/Catalina.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/Catalina.java Wed Mar 21 11:00:39 2007
@@ -302,13 +302,27 @@
                             "addLifecycleListener",
                             "org.apache.catalina.LifecycleListener");
 
+        //Executor
+        digester.addObjectCreate("Server/Service/Executor",
+                         "org.apache.catalina.core.StandardThreadExecutor",
+                         "className");
+        digester.addSetProperties("Server/Service/Executor");
+
+        digester.addSetNext("Server/Service/Executor",
+                            "addExecutor",
+                            "org.apache.catalina.Executor");
+
+        
         digester.addRule("Server/Service/Connector",
                          new ConnectorCreateRule());
         digester.addRule("Server/Service/Connector", 
-                         new SetAllPropertiesRule());
+                         new SetAllPropertiesRule(new String[]{"executor"}));
         digester.addSetNext("Server/Service/Connector",
                             "addConnector",
                             "org.apache.catalina.connector.Connector");
+        
+        
+
 
         digester.addObjectCreate("Server/Service/Connector/Listener",
                                  null, // MUST be specified in the element

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ConnectorCreateRule.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ConnectorCreateRule.java?view=diff&rev=520968&r1=520967&r2=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ConnectorCreateRule.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ConnectorCreateRule.java Wed Mar 21 11:00:39 2007
@@ -23,6 +23,10 @@
 import org.apache.catalina.connector.Connector;
 import org.apache.tomcat.util.digester.Rule;
 import org.xml.sax.Attributes;
+import org.apache.catalina.Service;
+import org.apache.catalina.Executor;
+import org.apache.tomcat.util.IntrospectionUtils;
+import java.lang.reflect.Method;
 
 
 /**
@@ -41,7 +45,20 @@
      * @param attributes The attribute list of this element
      */
     public void begin(Attributes attributes) throws Exception {
-        digester.push(new Connector(attributes.getValue("protocol")));
+        Service svc = (Service)digester.peek();
+        Executor ex = null;
+        if ( attributes.getValue("executor")!=null ) {
+            ex = svc.getExecutor(attributes.getValue("executor"));
+        }
+        Connector con = new Connector(attributes.getValue("protocol"));
+        if ( ex != null )  _setExecutor(con,ex);
+        
+        digester.push(con);
+    }
+    
+    public void _setExecutor(Connector con, Executor ex) throws Exception {
+        Method m = IntrospectionUtils.findMethod(con.getProtocolHandler().getClass(),"setExecutor",new Class[] {java.util.concurrent.Executor.class});
+        m.invoke(con.getProtocolHandler(),new Object[] {ex});
     }
 
 

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/EngineRuleSet.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/EngineRuleSet.java?view=diff&rev=520968&r1=520967&r2=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/EngineRuleSet.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/EngineRuleSet.java Wed Mar 21 11:00:39 2007
@@ -89,7 +89,7 @@
      *  should be added.
      */
     public void addRuleInstances(Digester digester) {
-
+        
         digester.addObjectCreate(prefix + "Engine",
                                  "org.apache.catalina.core.StandardEngine",
                                  "className");

Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/SetAllPropertiesRule.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/SetAllPropertiesRule.java?view=diff&rev=520968&r1=520967&r2=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/SetAllPropertiesRule.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/SetAllPropertiesRule.java Wed Mar 21 11:00:39 2007
@@ -22,20 +22,26 @@
 
 import org.apache.tomcat.util.IntrospectionUtils;
 import org.apache.tomcat.util.digester.Rule;
+import java.util.HashMap;
 
 /**
  * Rule that uses the introspection utils to set properties.
  * 
  * @author Remy Maucherat
+ * @author Filip Hanik
  */
 public class SetAllPropertiesRule extends Rule {
 
-
+    
     // ----------------------------------------------------------- Constructors
-
+    public SetAllPropertiesRule() {}
+    
+    public SetAllPropertiesRule(String[] exclude) {
+        for (int i=0; i<exclude.length; i++ ) if (exclude[i]!=null) this.excludes.put(exclude[i],exclude[i]);
+    }
 
     // ----------------------------------------------------- Instance Variables
-
+    protected HashMap<String,String> excludes = new HashMap<String,String>();
 
     // --------------------------------------------------------- Public Methods
 
@@ -56,7 +62,8 @@
                 name = attributes.getQName(i);
             }
             String value = attributes.getValue(i);
-            IntrospectionUtils.setProperty(digester.peek(), name, value);
+            if ( !excludes.containsKey(name)) 
+                IntrospectionUtils.setProperty(digester.peek(), name, value);
         }
 
     }

Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?view=diff&rev=520968&r1=520967&r2=520968
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Wed Mar 21 11:00:39 2007
@@ -777,10 +777,13 @@
         nioChannels.clear();
         processorCache.clear();
         if ( executor!=null ) {
-            ThreadPoolExecutor tpe = (ThreadPoolExecutor)executor;
-            tpe.shutdown();
-            TaskQueue queue = (TaskQueue)tpe.getQueue();
-            queue.setParent(null);
+            if ( executor instanceof ThreadPoolExecutor ) {
+                //this is our internal one, so we need to shut it down
+                ThreadPoolExecutor tpe = (ThreadPoolExecutor) executor;
+                tpe.shutdown();
+                TaskQueue queue = (TaskQueue) tpe.getQueue();
+                queue.setParent(null);
+            }
             executor = null;
         }
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org