Coverage Report - org.mule.impl.work.MuleWorkManager
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleWorkManager
0%
0/70
0%
0/7
2
 
 1  
 /*
 2  
  * $Id: MuleWorkManager.java 7976 2007-08-21 14:26:13Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 /**
 12  
  *
 13  
  * Copyright 2004 The Apache Software Foundation
 14  
  *
 15  
  *  Licensed under the Apache License, Version 2.0 (the "License");
 16  
  *  you may not use this file except in compliance with the License.
 17  
  *  You may obtain a copy of the License at
 18  
  *
 19  
  *     http://www.apache.org/licenses/LICENSE-2.0
 20  
  *
 21  
  *  Unless required by applicable law or agreed to in writing, software
 22  
  *  distributed under the License is distributed on an "AS IS" BASIS,
 23  
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 24  
  *  See the License for the specific language governing permissions and
 25  
  *  limitations under the License.
 26  
  */
 27  
 
 28  
 package org.mule.impl.work;
 29  
 
 30  
 import org.mule.MuleManager;
 31  
 import org.mule.config.ThreadingProfile;
 32  
 import org.mule.umo.UMOException;
 33  
 import org.mule.umo.manager.UMOWorkManager;
 34  
 
 35  
 import java.util.List;
 36  
 
 37  
 import javax.resource.spi.XATerminator;
 38  
 import javax.resource.spi.work.ExecutionContext;
 39  
 import javax.resource.spi.work.Work;
 40  
 import javax.resource.spi.work.WorkCompletedException;
 41  
 import javax.resource.spi.work.WorkException;
 42  
 import javax.resource.spi.work.WorkListener;
 43  
 
 44  
 import edu.emory.mathcs.backport.java.util.concurrent.Executor;
 45  
 import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
 46  
 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
 47  
 import org.apache.commons.logging.Log;
 48  
 import org.apache.commons.logging.LogFactory;
 49  
 
 50  
 /**
 51  
  * <code>MuleWorkManager</code> is a JCA Work manager implementation used to manage
 52  
  * thread allocation for Mule components and connectors. This code has been adapted
 53  
  * from the Geronimo implementation.
 54  
  */
 55  
 public class MuleWorkManager implements UMOWorkManager
 56  
 {
 57  
     /**
 58  
      * logger used by this class
 59  
      */
 60  0
     protected static final Log logger = LogFactory.getLog(MuleWorkManager.class);
 61  
 
 62  
     /**
 63  
      * Graceful shutdown delay
 64  
      */
 65  
     private static final long SHUTDOWN_TIMEOUT = 5000L;
 66  
 
 67  
     /**
 68  
      * The ThreadingProfile used for creation of the underlying ExecutorService
 69  
      */
 70  
     private final ThreadingProfile threadingProfile;
 71  
 
 72  
     /**
 73  
      * The actual pool of threads used by this MuleWorkManager to process the Work
 74  
      * instances submitted via the (do,start,schedule)Work methods.
 75  
      */
 76  
     private volatile ExecutorService workExecutorService;
 77  
     private final String name;
 78  
 
 79  
     /**
 80  
      * Various policies used for work execution
 81  
      */
 82  0
     private final WorkExecutor scheduleWorkExecutor = new ScheduleWorkExecutor();
 83  0
     private final WorkExecutor startWorkExecutor = new StartWorkExecutor();
 84  0
     private final WorkExecutor syncWorkExecutor = new SyncWorkExecutor();
 85  
 
 86  
     public MuleWorkManager()
 87  
     {
 88  0
         this(MuleManager.getConfiguration().getDefaultThreadingProfile(), null);
 89  0
     }
 90  
 
 91  
     public MuleWorkManager(ThreadingProfile profile, String name)
 92  
     {
 93  0
         super();
 94  
 
 95  0
         if (name == null)
 96  
         {
 97  0
             name = "WorkManager#" + hashCode();
 98  
         }
 99  
 
 100  0
         this.threadingProfile = profile;
 101  0
         this.name = name;
 102  0
     }
 103  
 
 104  
     public synchronized void start() throws UMOException
 105  
     {
 106  0
         if (workExecutorService == null)
 107  
         {
 108  0
             workExecutorService = threadingProfile.createPool(name);
 109  
         }
 110  0
     }
 111  
 
 112  
     public synchronized void stop() throws UMOException
 113  
     {
 114  0
         if (workExecutorService != null)
 115  
         {
 116  
             try
 117  
             {
 118  
                 // Cancel currently executing tasks
 119  0
                 List outstanding = workExecutorService.shutdownNow();
 120  
 
 121  
                 // Wait a while for existing tasks to terminate
 122  0
                 if (!workExecutorService.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS))
 123  
                 {
 124  0
                     logger.warn("Pool " + name + " did not terminate in time; " + outstanding.size()
 125  
                                     + " work items were cancelled.");
 126  
                 }
 127  
             }
 128  0
             catch (InterruptedException ie)
 129  
             {
 130  
                 // (Re-)Cancel if current thread also interrupted
 131  0
                 workExecutorService.shutdownNow();
 132  
                 // Preserve interrupt status
 133  0
                 Thread.currentThread().interrupt();
 134  
             }
 135  
             finally
 136  
             {
 137  0
                 workExecutorService = null;
 138  0
             }
 139  
         }
 140  0
     }
 141  
 
 142  
     public void dispose()
 143  
     {
 144  
         try
 145  
         {
 146  0
             stop();
 147  
         }
 148  0
         catch (UMOException e)
 149  
         {
 150  
             // TODO MULE-863: Is this serious?
 151  0
             logger.warn("Error while disposing Work Manager: " + e.getMessage(), e);
 152  0
         }
 153  0
     }
 154  
 
 155  
     // TODO
 156  
     public XATerminator getXATerminator()
 157  
     {
 158  0
         return null;
 159  
     }
 160  
 
 161  
     /*
 162  
      * (non-Javadoc)
 163  
      * 
 164  
      * @see javax.resource.spi.work.MuleWorkManager#doWork(javax.resource.spi.work.Work)
 165  
      */
 166  
     public void doWork(Work work) throws WorkException
 167  
     {
 168  0
         executeWork(new WorkerContext(work), syncWorkExecutor);
 169  0
     }
 170  
 
 171  
     /*
 172  
      * (non-Javadoc)
 173  
      * 
 174  
      * @see javax.resource.spi.work.MuleWorkManager#doWork(javax.resource.spi.work.Work,
 175  
      *      long, javax.resource.spi.work.ExecutionContext,
 176  
      *      javax.resource.spi.work.WorkListener)
 177  
      */
 178  
     public void doWork(Work work, long startTimeout, ExecutionContext execContext, WorkListener workListener)
 179  
         throws WorkException
 180  
     {
 181  0
         WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
 182  0
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
 183  0
         executeWork(workWrapper, syncWorkExecutor);
 184  0
     }
 185  
 
 186  
     /*
 187  
      * (non-Javadoc)
 188  
      * 
 189  
      * @see javax.resource.spi.work.MuleWorkManager#startWork(javax.resource.spi.work.Work)
 190  
      */
 191  
     public long startWork(Work work) throws WorkException
 192  
     {
 193  0
         WorkerContext workWrapper = new WorkerContext(work);
 194  0
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
 195  0
         executeWork(workWrapper, startWorkExecutor);
 196  0
         return System.currentTimeMillis() - workWrapper.getAcceptedTime();
 197  
     }
 198  
 
 199  
     /*
 200  
      * (non-Javadoc)
 201  
      * 
 202  
      * @see javax.resource.spi.work.MuleWorkManager#startWork(javax.resource.spi.work.Work,
 203  
      *      long, javax.resource.spi.work.ExecutionContext,
 204  
      *      javax.resource.spi.work.WorkListener)
 205  
      */
 206  
     public long startWork(Work work,
 207  
                           long startTimeout,
 208  
                           ExecutionContext execContext,
 209  
                           WorkListener workListener) throws WorkException
 210  
     {
 211  0
         WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
 212  0
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
 213  0
         executeWork(workWrapper, startWorkExecutor);
 214  0
         return System.currentTimeMillis() - workWrapper.getAcceptedTime();
 215  
     }
 216  
 
 217  
     /*
 218  
      * (non-Javadoc)
 219  
      * 
 220  
      * @see javax.resource.spi.work.MuleWorkManager#scheduleWork(javax.resource.spi.work.Work)
 221  
      */
 222  
     public void scheduleWork(Work work) throws WorkException
 223  
     {
 224  0
         WorkerContext workWrapper = new WorkerContext(work);
 225  0
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
 226  0
         executeWork(workWrapper, scheduleWorkExecutor);
 227  0
     }
 228  
 
 229  
     /*
 230  
      * (non-Javadoc)
 231  
      * 
 232  
      * @see javax.resource.spi.work.MuleWorkManager#scheduleWork(javax.resource.spi.work.Work,
 233  
      *      long, javax.resource.spi.work.ExecutionContext,
 234  
      *      javax.resource.spi.work.WorkListener)
 235  
      */
 236  
     public void scheduleWork(Work work,
 237  
                              long startTimeout,
 238  
                              ExecutionContext execContext,
 239  
                              WorkListener workListener) throws WorkException
 240  
     {
 241  0
         WorkerContext workWrapper = new WorkerContext(work, startTimeout, execContext, workListener);
 242  0
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
 243  0
         executeWork(workWrapper, scheduleWorkExecutor);
 244  0
     }
 245  
 
 246  
     /**
 247  
      * @see Executor#execute(Runnable)
 248  
      */
 249  
     public void execute(Runnable work)
 250  
     {
 251  0
         if (workExecutorService == null || workExecutorService.isShutdown())
 252  
         {
 253  0
             throw new IllegalStateException("This MuleWorkManager is stopped");
 254  
         }
 255  
 
 256  0
         workExecutorService.execute(work);
 257  0
     }
 258  
 
 259  
     /**
 260  
      * Execute the specified Work.
 261  
      * 
 262  
      * @param work Work to be executed.
 263  
      * @exception WorkException Indicates that the Work execution has been
 264  
      *                unsuccessful.
 265  
      */
 266  
     private void executeWork(WorkerContext work, WorkExecutor workExecutor) throws WorkException
 267  
     {
 268  0
         if (workExecutorService == null || workExecutorService.isShutdown())
 269  
         {
 270  0
             throw new IllegalStateException("This MuleWorkManager is stopped");
 271  
         }
 272  
 
 273  
         try
 274  
         {
 275  0
             work.workAccepted(this);
 276  0
             workExecutor.doExecute(work, workExecutorService);
 277  0
             WorkException exception = work.getWorkException();
 278  0
             if (null != exception)
 279  
             {
 280  0
                 throw exception;
 281  
             }
 282  
         }
 283  0
         catch (InterruptedException e)
 284  
         {
 285  0
             WorkCompletedException wcj = new WorkCompletedException("The execution has been interrupted.", e);
 286  0
             wcj.setErrorCode(WorkException.INTERNAL);
 287  0
             throw wcj;
 288  0
         }
 289  0
     }
 290  
 
 291  
 }