[jboss-cvs] JBossAS SVN: r90898 - in trunk/server/src: etc/conf/all/bootstrap and 2 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Jul 7 13:37:25 EDT 2009
Author: kabir.khan at jboss.com
Date: 2009-07-07 13:37:25 -0400 (Tue, 07 Jul 2009)
New Revision: 90898
Added:
trunk/server/src/etc/conf/all/bootstrap/asynch.xml
trunk/server/src/main/org/jboss/executor/
trunk/server/src/main/org/jboss/executor/ControllerExecutorInstaller.java
trunk/server/src/main/org/jboss/executor/ThreadPoolExecutorFactory.java
Modified:
trunk/server/src/etc/conf/all/bootstrap.xml
Log:
[JBAS-7083] Add bean to install Executor in AbstractController to AS bootstrap
Added: trunk/server/src/etc/conf/all/bootstrap/asynch.xml
===================================================================
--- trunk/server/src/etc/conf/all/bootstrap/asynch.xml (rev 0)
+++ trunk/server/src/etc/conf/all/bootstrap/asynch.xml 2009-07-07 17:37:25 UTC (rev 90898)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ The Executor used by the controller to do asynchronous deployments
+-->
+<deployment xmlns="urn:jboss:bean-deployer:2.0">
+ <classloader><inject bean="asynch-classloader:0.0.0"/></classloader>
+
+ <classloader name="asynch-classloader" xmlns="urn:jboss:classloader:1.0" export-all="NON_EMPTY" import-all="true">
+ <root>${jboss.common.lib.url}jboss.jar</root>
+ </classloader>
+
+ <bean name="BootstrapExecutorFactory" class="org.jboss.executor.ThreadPoolExecutorFactory">
+ <property name="corePoolSizeBase">5</property>
+ <property name="corePoolSizePerCpu">2</property>
+ <property name="maxPoolSizeBase">10</property>
+ <property name="maxPoolSizePerCpu">3</property>
+ </bean>
+
+ <bean name="ControllerExecutorInstaller" class="org.jboss.executor.ControllerExecutorInstaller">
+ <property name="context"><inject fromContext="context"/></property>
+ <property name="bootstrapExecutor"><inject bean="BootstrapExecutorFactory" property="executor"/></property>
+ <property name="mainExecutor"><inject bean="ThreadPool" option="Callback"/></property>
+ </bean>
+</deployment>
Modified: trunk/server/src/etc/conf/all/bootstrap.xml
===================================================================
--- trunk/server/src/etc/conf/all/bootstrap.xml 2009-07-07 16:44:34 UTC (rev 90897)
+++ trunk/server/src/etc/conf/all/bootstrap.xml 2009-07-07 17:37:25 UTC (rev 90898)
@@ -8,9 +8,9 @@
<url>bootstrap/logging.xml</url>
<url>bootstrap/vfs.xml</url>
<url>bootstrap/classloader.xml</url>
+ <url>bootstrap/asynch.xml</url>
<url>bootstrap/aop.xml</url>
<url>bootstrap/jmx.xml</url>
<url>bootstrap/deployers.xml</url>
<url>bootstrap/profile.xml</url>
-
</bootstrap>
Added: trunk/server/src/main/org/jboss/executor/ControllerExecutorInstaller.java
===================================================================
--- trunk/server/src/main/org/jboss/executor/ControllerExecutorInstaller.java (rev 0)
+++ trunk/server/src/main/org/jboss/executor/ControllerExecutorInstaller.java 2009-07-07 17:37:25 UTC (rev 90898)
@@ -0,0 +1,145 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.executor;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.jboss.dependency.plugins.AbstractController;
+import org.jboss.dependency.spi.ControllerContext;
+
+/**
+ * Executor implementation which installs itself in the controller to be used for asynchronous deployments.
+ * It wraps two executors. One used during bootstrap ({@link #setBootstrapExecutor(Executor)}),
+ * and one which is deployed later ({@link #setMainExecutor(Executor)}).
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ControllerExecutorInstaller implements Executor
+{
+ ControllerContext context;
+
+ volatile Executor bootstrapExecutor;
+
+ volatile Executor mainExecutor;
+
+ /**
+ * Contextual injection
+ *
+ * @return My ControllerContext
+ */
+ public ControllerContext getContext()
+ {
+ return context;
+ }
+
+ /**
+ * Contextual injection
+ *
+ * @param context My ControllerContext
+ */
+ public void setContext(ControllerContext context)
+ {
+ this.context = context;
+ }
+
+ /**
+ * Get the bootstrap executor to be used until the main executor is deployed.
+ *
+ * @return The bootstrap executor
+ */
+ public Executor getBootstrapExecutor()
+ {
+ return bootstrapExecutor;
+ }
+
+ /**
+ * Set the bootstrap executor to be used until the main executor is deployed.
+ *
+ * @param mainExecutor The bootstrap executor.
+ */
+ public void setBootstrapExecutor(Executor executor)
+ {
+ this.bootstrapExecutor = executor;
+ }
+
+ /**
+ * Set the main executor once that is deployed
+ * @param mainExecutor The system executor
+ */
+ public Executor getMainExecutor()
+ {
+ return mainExecutor;
+ }
+
+ /**
+ * Set the main executor once that is deployed
+ * @param mainExecutor The system executor
+ */
+ public void setMainExecutor(Executor mainExecutor)
+ {
+ this.mainExecutor = mainExecutor;
+ }
+
+ /**
+ * Set myself as the executor in the controller
+ */
+ public void start()
+ {
+ ((AbstractController)context.getController()).setExecutor(this);
+ }
+
+ /**
+ * Unset myself as the executor in the controller
+ */
+ public void stop()
+ {
+ ((AbstractController)context.getController()).setExecutor(null);
+ }
+
+ /**
+ * Execute the command, using the mainExecutor if available. If there
+ * is no mainExecutor, use the bootstrapExecutor.
+ * @param command the command to execute
+ * @throws java.util.concurrent.RejectedExecutionException if there is no mainExecutor or bootstrapExecutor
+ * @see Executor#execute(Runnable)
+ */
+ public void execute(Runnable command)
+ {
+ Executor exec = mainExecutor;
+ if (exec != null)
+ {
+ exec.execute(command);
+ return;
+ }
+
+ exec = bootstrapExecutor;
+ if (exec != null)
+ {
+ exec.execute(command);
+ return;
+ }
+
+ throw new RejectedExecutionException("No executor available in " + this.getClass().getName());
+ }
+}
Added: trunk/server/src/main/org/jboss/executor/ThreadPoolExecutorFactory.java
===================================================================
--- trunk/server/src/main/org/jboss/executor/ThreadPoolExecutorFactory.java (rev 0)
+++ trunk/server/src/main/org/jboss/executor/ThreadPoolExecutorFactory.java 2009-07-07 17:37:25 UTC (rev 90898)
@@ -0,0 +1,301 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.executor;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Creates a ThreadPoolExecutor that can be configured as an MC bean.
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ThreadPoolExecutorFactory
+{
+ final static ThreadFactory DEFAULT_THREAD_FACTORY = Executors.defaultThreadFactory();
+
+ final static RejectedExecutionHandler DEFAULT_REJECTED_EXECUTION_HANDLER = new ThreadPoolExecutor.AbortPolicy();
+
+ final static int DEFAULT_KEEP_ALIVE_TIME = 30;
+
+ final static TimeUnit DEFAULT_KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
+
+ float corePoolSizeBase;
+
+ float corePoolSizePerCpu;
+
+ float maxPoolSizeBase;
+
+ float maxPoolSizePerCpu;
+
+ int keepAliveTime;
+
+ TimeUnit keepAliveTimeUnit = TimeUnit.SECONDS;
+
+ BlockingQueue<Runnable> workQueue;
+
+ ThreadFactory threadFactory;
+
+ RejectedExecutionHandler rejectedExecutionHandler;
+
+ Executor executor;
+
+ /**
+ * Gets the keep alive time to be used in the created pool.
+ * @return the keep alive time
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public int getKeepAliveTime()
+ {
+ return keepAliveTime;
+ }
+
+ /**
+ * Sets the keep alive time to be used in the created pool.
+ * @param keepAliveTime The time
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setKeepAliveTime(int keepAliveTime)
+ {
+ this.keepAliveTime = keepAliveTime;
+ }
+
+ /**
+ * Gets the time unit for keep alive time to be used in the created pool.
+ * @return The keep alive time unit
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public TimeUnit getKeepAliveTimeUnit()
+ {
+ return keepAliveTimeUnit;
+ }
+
+ /**
+ * Sets the time unit for keep alive time to be used in the created pool. The default is TimeUnit.SECONDS
+ * @param keepAliveTimeUnit The time unit
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setKeepAliveTimeUnit(TimeUnit keepAliveTimeUnit)
+ {
+ this.keepAliveTimeUnit = keepAliveTimeUnit;
+ }
+
+ /**
+ * Gets work queue to be used in the created pool.
+ * @return The work queue
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public BlockingQueue<Runnable> getWorkQueue()
+ {
+ return workQueue;
+ }
+
+ /**
+ * Sets the work queue to be used in the created pool. By default it will create an instance of {@link LinkedBlockingQueue}
+ * @param workQueue The work queue
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setWorkQueue(BlockingQueue<Runnable> workQueue)
+ {
+ this.workQueue = workQueue;
+ }
+
+ /**
+ * Gets the thread factory to be used in the created pool.
+ * @return The thread factory
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public ThreadFactory getThreadFactory()
+ {
+ return threadFactory;
+ }
+
+ /**
+ * Sets the thread factory to be used in the created pool. By default it will use {@link Executors#defaultThreadFactory()}
+ * @return The thread factory
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setThreadFactory(ThreadFactory threadFactory)
+ {
+ this.threadFactory = threadFactory;
+ }
+
+ /**
+ * Gets the base value for the calculation of the core pool size to be used as the corePoolSize argument in the created pool.
+ * @return the base core pool size
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public float getCorePoolSizeBase()
+ {
+ return corePoolSizeBase;
+ }
+
+ /**
+ * Sets the base value for the calculation of the core pool size to be used as the corePoolSize argument in the created pool.
+ * The calculation is <code>corePoolSizeBase + (corePoolSizePerCpu * Runtime.availableProcessors())</code>
+ * @param the base core pool size
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setCorePoolSizeBase(float corePoolSizeBase)
+ {
+ this.corePoolSizeBase = corePoolSizeBase;
+ }
+
+ /**
+ * Gets the per cpu value for the calculation of the core pool size to be used as the corePoolSize argument in the created pool.
+ * @return the per cpu core pool size
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public float getCorePoolSizePerCpu()
+ {
+ return corePoolSizePerCpu;
+ }
+
+ /**
+ * Sets the per cpu value for the calculation of the core pool size to be used as the corePoolSize argument in the created pool.
+ * The calculation is <code>corePoolSizeBase + (corePoolSizePerCpu * Runtime.availableProcessors())</code>
+ * @param the per cpu core pool size
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setCorePoolSizePerCpu(float corePoolSizePerCpu)
+ {
+ this.corePoolSizePerCpu = corePoolSizePerCpu;
+ }
+
+ /**
+ * Gets the base value for the calculation of the max pool size to be used as the maxPoolSize in the created pool.
+ * @return the base max pool size
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public float getMaxPoolSizeBase()
+ {
+ return maxPoolSizeBase;
+ }
+
+ /**
+ * Sets the base value for the calculation of the max pool size to be used as the maxPoolSize argument in the created pool.
+ * The calculation is <code>maxPoolSizeBase + (maxPoolSizePerCpu * Runtime.availableProcessors())</code>
+ * @param the base max pool size
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setMaxPoolSizeBase(float maxPoolSizeBase)
+ {
+ this.maxPoolSizeBase = maxPoolSizeBase;
+ }
+
+ /**
+ * Gets the per cpu value for the calculation of the max pool size to be used as the maxPoolSize argument in the created pool.
+ * @return the per cpu max pool size
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public float getMaxPoolSizePerCpu()
+ {
+ return maxPoolSizePerCpu;
+ }
+
+ /**
+ * Sets the per cpu value for the calculation of the max pool size to be used as the maxPoolSize argument in the created pool.
+ * The calculation is <code>maxPoolSizeBase + (maxPoolSizePerCpu * Runtime.availableProcessors())</code>
+ * @param the per cpu max pool size
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setMaxPoolSizePerCpu(float maxPoolSizePerCpu)
+ {
+ this.maxPoolSizePerCpu = maxPoolSizePerCpu;
+ }
+
+ /**
+ * Gets the rejected execution handler to be used in the created pool.
+ * @return The rejected execution handler
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public RejectedExecutionHandler getRejectedExecutionHandler()
+ {
+ return rejectedExecutionHandler;
+ }
+
+ /**
+ * Sets the rejected execution handler to be used in the created pool. The default is to create an instance of {@link ThreadPoolExecutor.AbortPolicy}
+ * @param rejectedExecutionHandler The rejected execution handler
+ * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)}
+ */
+ public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler)
+ {
+ this.rejectedExecutionHandler = rejectedExecutionHandler;
+ }
+
+ /**
+ * Creates and returns an instance of the ThreadPoolExecutor configured by this bean. Subsequent invocations
+ * will return the same instance.
+ * @return The created executor
+ */
+ public Executor getExecutor()
+ {
+ synchronized(this)
+ {
+ if (executor == null)
+ {
+ executor = createExecutor();
+ }
+ }
+ return executor;
+ }
+
+ private ThreadPoolExecutor createExecutor()
+ {
+ int coreSize = Math.max(calcPoolSize(corePoolSizeBase, corePoolSizePerCpu), 0);
+ if (coreSize == 0)
+ {
+ throw new IllegalStateException("Core size was calculated to 0");
+ }
+ int maxSize = Math.max(calcPoolSize(maxPoolSizeBase, maxPoolSizePerCpu), 0);
+ if (maxSize == 0)
+ {
+ throw new IllegalStateException("Max size was calculated to 0");
+ }
+ BlockingQueue<Runnable> queue = workQueue == null ? new LinkedBlockingQueue<Runnable>() : workQueue;
+ ThreadFactory factory = threadFactory == null ? DEFAULT_THREAD_FACTORY : threadFactory;
+ RejectedExecutionHandler handler = rejectedExecutionHandler == null ? DEFAULT_REJECTED_EXECUTION_HANDLER : rejectedExecutionHandler;
+
+ return new ThreadPoolExecutor(coreSize, maxSize, keepAliveTime, keepAliveTimeUnit, queue, factory, handler);
+ }
+
+ private static int calcPoolSize(float count, float perCpu)
+ {
+ if (Float.isNaN(count) || Float.isInfinite(count) || count < 0.0f)
+ {
+ count = 0.0f;
+ }
+ if (Float.isNaN(perCpu) || Float.isInfinite(perCpu) || perCpu < 0.0f)
+ {
+ perCpu = 0.0f;
+ }
+ return Math.round(count + ((float) Runtime.getRuntime().availableProcessors()) * perCpu);
+ }
+}
More information about the jboss-cvs-commits
mailing list