Coverage Report - org.kuali.rice.ksb.messaging.threadpool.KSBThreadPoolImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
KSBThreadPoolImpl
0%
0/30
0%
0/4
1.3
KSBThreadPoolImpl$KSBThreadFactory
0%
0/12
N/A
1.3
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.ksb.messaging.threadpool;
 17  
 
 18  
 import org.apache.log4j.Logger;
 19  
 import org.kuali.rice.core.api.config.CoreConfigHelper;
 20  
 import org.kuali.rice.core.api.config.property.Config;
 21  
 import org.kuali.rice.core.api.config.property.ConfigContext;
 22  
 import org.kuali.rice.core.api.util.ClassLoaderUtils;
 23  
 
 24  
 import java.util.concurrent.Executors;
 25  
 import java.util.concurrent.PriorityBlockingQueue;
 26  
 import java.util.concurrent.ThreadFactory;
 27  
 import java.util.concurrent.ThreadPoolExecutor;
 28  
 import java.util.concurrent.TimeUnit;
 29  
 
 30  
 /**
 31  
  * A Thread Pool implementation for the KSB which implements a thread pool backed by a configuration store.
 32  
  *
 33  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 34  
  */
 35  
 public class KSBThreadPoolImpl extends ThreadPoolExecutor implements KSBThreadPool {
 36  
 
 37  0
     private static final Logger LOG = Logger.getLogger(KSBThreadPoolImpl.class);
 38  
 
 39  
     public static final int DEFAULT_POOL_SIZE = 5;
 40  
 
 41  
     private boolean started;
 42  
     private boolean poolSizeSet;
 43  
 
 44  
     public KSBThreadPoolImpl() {
 45  0
             super(DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE, 60, TimeUnit.SECONDS, new PriorityBlockingQueue(1, new PriorityBlockingQueuePersistedMessageComparator()),  new KSBThreadFactory(ClassLoaderUtils.getDefaultClassLoader()), new ThreadPoolExecutor.AbortPolicy());
 46  0
     }
 47  
 
 48  
     public void setCorePoolSize(int corePoolSize) {
 49  0
                 LOG.info("Setting core pool size to " + corePoolSize + " threads.");
 50  0
                 super.setCorePoolSize(corePoolSize);
 51  0
                 this.poolSizeSet = true;
 52  0
     }
 53  
 
 54  
     public long getKeepAliveTime() {
 55  0
         return super.getKeepAliveTime(TimeUnit.MILLISECONDS);
 56  
     }
 57  
 
 58  
     public boolean isStarted() {
 59  0
         return this.started;
 60  
     }
 61  
 
 62  
     public void start() throws Exception {
 63  0
             LOG.info("Starting the KSB thread pool...");
 64  0
             loadSettings();
 65  0
             this.started = true;
 66  0
             LOG.info("...KSB thread pool successfully started.");
 67  0
     }
 68  
 
 69  
     public void stop() throws Exception {
 70  0
                 if (isStarted()) {
 71  0
                         LOG.info("Shutting down KSB thread pool...");
 72  0
                     this.shutdownNow();
 73  0
                     this.started = false;
 74  0
                     LOG.info("...KSB thread pool successfully shut down.");
 75  
                 }
 76  0
     }
 77  
 
 78  
     /**
 79  
          * Loads the thread pool settings from the DAO.
 80  
          */
 81  
     protected void loadSettings() {
 82  0
                 String threadPoolSizeStr = ConfigContext.getCurrentContextConfig().getProperty(Config.THREAD_POOL_SIZE);
 83  0
                 if (!this.poolSizeSet) {
 84  0
                     int poolSize = DEFAULT_POOL_SIZE;
 85  
                     try {
 86  0
                             poolSize = new Integer(threadPoolSizeStr);
 87  0
                     } catch (NumberFormatException nfe) {
 88  0
                             LOG.error( "loadSettings(): Unable to parse the pool size: '"+threadPoolSizeStr+"'");
 89  0
                     }
 90  0
                     setCorePoolSize(poolSize);
 91  
                 }
 92  0
     }
 93  
 
 94  
     public Object getInstance() {
 95  0
             return this;
 96  
     }
 97  
 
 98  
     /**
 99  
          * A simple ThreadFactory which names the thread as follows:<br>
 100  
          * <br>
 101  
          *
 102  
          * <i>applicationId</i>/KSB-pool-<i>m</i>-thread-<i>n</i><br>
 103  
          * <br>
 104  
          *
 105  
          * Where <i>applicationId</i> is the id of the application running the thread pool, <i>m</i> is the
 106  
          * sequence number of the factory and <i>n</i> is the sequence number of the thread within the factory.
 107  
          *
 108  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 109  
          */
 110  
     private static class KSBThreadFactory implements ThreadFactory {
 111  
 
 112  0
         private static int factorySequence = 0;
 113  
 
 114  0
         private static int threadSequence = 0;
 115  
 
 116  0
         private ThreadFactory defaultThreadFactory = Executors.defaultThreadFactory();
 117  
 
 118  
         private ClassLoader contextClassLoader;
 119  
 
 120  0
         public KSBThreadFactory(ClassLoader contextClassLoader) {
 121  0
             this.contextClassLoader = contextClassLoader;
 122  0
             factorySequence++;
 123  0
         }
 124  
 
 125  
         public Thread newThread(Runnable runnable) {
 126  0
             threadSequence++;
 127  0
             Thread thread = this.defaultThreadFactory.newThread(runnable);
 128  
             // if the thread ends up getting spawned by an action inside of a workflow plugin or something along those lines, it will inherit the plugin's
 129  
             // classloader as it's ContextClassLoader.  Let's make sure it's set to the same ClassLoader that loaded the KSBConfigurer
 130  0
             thread.setContextClassLoader(contextClassLoader);
 131  0
             thread.setName(CoreConfigHelper.getApplicationId() + "/KSB-pool-" + factorySequence + "-thread-"
 132  
                     + threadSequence);
 133  0
             return thread;
 134  
         }
 135  
 
 136  
     }
 137  
 }