Author: davsclaus
Date: Fri Sep  7 07:51:31 2012
New Revision: 1381918

URL: http://svn.apache.org/viewvc?rev=1381918&view=rev
Log:
CAMEL-5563: API for shutdown thread pool in ExecutorServiceManager aligned so 
they use the API of the JDK as well the new shutdownGraceful. This gives end 
user full power what to use.

Modified:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultExecutorServiceManager.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultShutdownStrategy.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ExecutorServiceManager.java

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultExecutorServiceManager.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultExecutorServiceManager.java?rev=1381918&r1=1381917&r2=1381918&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultExecutorServiceManager.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultExecutorServiceManager.java
 Fri Sep  7 07:51:31 2012
@@ -59,7 +59,7 @@ public class DefaultExecutorServiceManag
     private ThreadPoolFactory threadPoolFactory = new 
DefaultThreadPoolFactory();
     private final List<ExecutorService> executorServices = new 
ArrayList<ExecutorService>();
     private String threadNamePattern;
-    private long shutdownAwaitTermination = 30000;
+    private long shutdownAwaitTermination = 10000;
     private String defaultThreadPoolProfileId = "defaultThreadPoolProfile";
     private final Map<String, ThreadPoolProfile> threadPoolProfiles = new 
HashMap<String, ThreadPoolProfile>();
     private ThreadPoolProfile builtIndefaultProfile;
@@ -256,41 +256,50 @@ public class DefaultExecutorServiceManag
 
     @Override
     public void shutdown(ExecutorService executorService) {
-        ObjectHelper.notNull(executorService, "executorService");
-        shutdown(executorService, shutdownAwaitTermination);
+        doShutdown(executorService, 0);
     }
 
     @Override
-    public void shutdown(ExecutorService executorService, long 
shutdownAwaitTermination) {
-        ObjectHelper.notNull(executorService, "executorService");
-        if (shutdownAwaitTermination <= 0) {
-            throw new IllegalArgumentException("ShutdownAwaitTermination must 
be a positive number, was: " + shutdownAwaitTermination);
-        }
+    public void shutdownGraceful(ExecutorService executorService) {
+        doShutdown(executorService, getShutdownAwaitTermination());
+    }
+
+    @Override
+    public void shutdownGraceful(ExecutorService executorService, long 
shutdownAwaitTermination) {
+        doShutdown(executorService, shutdownAwaitTermination);
+    }
 
+    private void doShutdown(ExecutorService executorService, long 
shutdownAwaitTermination) {
+        ObjectHelper.notNull(executorService, "executorService");
 
         // shutting down a thread pool is a 2 step process. First we try 
graceful, and if that fails, then we go more aggressively
         // and try shutting down again. In both cases we wait at most the 
given shutdown timeout value given
-        // (total wait could then be 2 x shutdownAwaitTermination)
-        boolean warned = false;
-        StopWatch watch = new StopWatch();
+        // (total wait could then be 2 x shutdownAwaitTermination, but when we 
shutdown the 2nd time we are aggressive and thus
+        // we ought to shutdown much faster)
         if (!executorService.isShutdown()) {
+            boolean warned = false;
+            StopWatch watch = new StopWatch();
+
             LOG.trace("Shutdown of ExecutorService: {} with await termination: 
{} millis", executorService, shutdownAwaitTermination);
             executorService.shutdown();
-            try {
-                if (!awaitTermination(executorService, 
shutdownAwaitTermination)) {
-                    warned = true;
-                    LOG.warn("Forcing shutdown of ExecutorService: {} due 
first await termination elapsed.", executorService);
-                    executorService.shutdownNow();
-                    // we are now shutting down aggressively, so wait to see 
if we can completely shutdown or not
+
+            if (shutdownAwaitTermination > 0) {
+                try {
                     if (!awaitTermination(executorService, 
shutdownAwaitTermination)) {
-                        LOG.warn("Cannot completely force shutdown of 
ExecutorService: {} due second await termination elapsed.", executorService);
+                        warned = true;
+                        LOG.warn("Forcing shutdown of ExecutorService: {} due 
first await termination elapsed.", executorService);
+                        executorService.shutdownNow();
+                        // we are now shutting down aggressively, so wait to 
see if we can completely shutdown or not
+                        if (!awaitTermination(executorService, 
shutdownAwaitTermination)) {
+                            LOG.warn("Cannot completely force shutdown of 
ExecutorService: {} due second await termination elapsed.", executorService);
+                        }
                     }
+                } catch (InterruptedException e) {
+                    warned = true;
+                    LOG.warn("Forcing shutdown of ExecutorService: {} due 
interrupted.", executorService);
+                    // we were interrupted during shutdown, so force shutdown
+                    executorService.shutdownNow();
                 }
-            } catch (InterruptedException e) {
-                warned = true;
-                LOG.warn("Forcing shutdown of ExecutorService: {} due 
interrupted.", executorService);
-                // we were interrupted during shutdown, so force shutdown
-                executorService.shutdownNow();
             }
 
             // if we logged at WARN level, then report at INFO level when we 
are complete so the end user can see this in the log
@@ -314,35 +323,6 @@ public class DefaultExecutorServiceManag
         executorServices.remove(executorService);
     }
 
-    /**
-     * Awaits the termination of the thread pool.
-     * <p/>
-     * This implementation will log every 5th second at INFO level that we are 
waiting, so the end user
-     * can see we are not hanging in case it takes longer time to shutdown the 
pool.
-     *
-     * @param executorService            the thread pool
-     * @param shutdownAwaitTermination   time in millis to use as timeout
-     * @return <tt>true</tt> if the pool is terminated, or <tt>false</tt> if 
we timed out
-     * @throws InterruptedException is thrown if we are interrupted during the 
waiting
-     */
-    private static boolean awaitTermination(ExecutorService executorService, 
long shutdownAwaitTermination) throws InterruptedException {
-        // log progress every 5th second so end user is aware of we are 
shutting down
-        StopWatch watch = new StopWatch();
-        long interval = Math.min(5000, shutdownAwaitTermination);
-        boolean done = false;
-        while (!done && interval > 0) {
-            if (executorService.awaitTermination(interval, 
TimeUnit.MILLISECONDS)) {
-                done = true;
-            } else {
-                LOG.info("Waited {} for ExecutorService: {} to shutdown...", 
TimeUtils.printDuration(watch.taken()), executorService);
-                // recalculate interval
-                interval = Math.min(5000, shutdownAwaitTermination - 
watch.taken());
-            }
-        }
-
-        return done;
-    }
-
     @Override
     public List<Runnable> shutdownNow(ExecutorService executorService) {
         return doShutdownNow(executorService, false);
@@ -373,7 +353,7 @@ public class DefaultExecutorServiceManag
             }
         }
 
-        // remove reference as its shutdown
+        // remove reference as its shutdown (do not remove if fail-safe)
         if (!failSafe) {
             executorServices.remove(executorService);
         }
@@ -381,6 +361,25 @@ public class DefaultExecutorServiceManag
         return answer;
     }
 
+    @Override
+    public boolean awaitTermination(ExecutorService executorService, long 
shutdownAwaitTermination) throws InterruptedException {
+        // log progress every 2nd second so end user is aware of we are 
shutting down
+        StopWatch watch = new StopWatch();
+        long interval = Math.min(2000, shutdownAwaitTermination);
+        boolean done = false;
+        while (!done && interval > 0) {
+            if (executorService.awaitTermination(interval, 
TimeUnit.MILLISECONDS)) {
+                done = true;
+            } else {
+                LOG.info("Waited {} for ExecutorService: {} to terminate...", 
TimeUtils.printDuration(watch.taken()), executorService);
+                // recalculate interval
+                interval = Math.min(2000, shutdownAwaitTermination - 
watch.taken());
+            }
+        }
+
+        return done;
+    }
+
     /**
      * Strategy callback when a new {@link 
java.util.concurrent.ExecutorService} have been created.
      *

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultShutdownStrategy.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultShutdownStrategy.java?rev=1381918&r1=1381917&r2=1381918&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultShutdownStrategy.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultShutdownStrategy.java
 Fri Sep  7 07:51:31 2012
@@ -355,7 +355,8 @@ public class DefaultShutdownStrategy ext
     @Override
     protected void doShutdown() throws Exception {
         if (executor != null) {
-            camelContext.getExecutorServiceManager().shutdown(executor);
+            // force shutting down as we are shutting down Camel
+            camelContext.getExecutorServiceManager().shutdownNow(executor);
             // should clear executor so we can restart by creating a new 
thread pool
             executor = null;
         }

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ExecutorServiceManager.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ExecutorServiceManager.java?rev=1381918&r1=1381917&r2=1381918&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ExecutorServiceManager.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ExecutorServiceManager.java
 Fri Sep  7 07:51:31 2012
@@ -129,7 +129,7 @@ public interface ExecutorServiceManager 
      * Sets the time to wait for thread pools to shutdown orderly, when 
invoking the
      * {@link #shutdown()} method.
      * <p/>
-     * The default value is <tt>30000</tt> millis.
+     * The default value is <tt>10000</tt> millis.
      *
      * @param timeInMillis time in millis.
      */
@@ -139,7 +139,7 @@ public interface ExecutorServiceManager 
      * Gets the time to wait for thread pools to shutdown orderly, when 
invoking the
      * {@link #shutdown()} method.
      * <p/>
-     * The default value is <tt>30000</tt> millis.
+     * The default value is <tt>10000</tt> millis.
      *
      * @return the timeout value
      */
@@ -271,6 +271,17 @@ public interface ExecutorServiceManager 
     ScheduledExecutorService newScheduledThreadPool(Object source, String 
name, String profileId);
 
     /**
+     * Shutdown the given executor service (<b>not</b> graceful).
+     * <p/>
+     * This implementation will issues a regular shutdown of the executor 
service,
+     * ie calling {@link java.util.concurrent.ExecutorService#shutdown()} and 
return.
+     *
+     * @param executorService the executor service to shutdown
+     * @see java.util.concurrent.ExecutorService#shutdown()
+     */
+    void shutdown(ExecutorService executorService);
+
+    /**
      * Shutdown the given executor service graceful at first, and then 
aggressively
      * if the await termination timeout was hit.
      * <p/>
@@ -285,7 +296,7 @@ public interface ExecutorServiceManager 
      * @see java.util.concurrent.ExecutorService#shutdown()
      * @see #getShutdownAwaitTermination()
      */
-    void shutdown(ExecutorService executorService);
+    void shutdownGraceful(ExecutorService executorService);
 
     /**
      * Shutdown the given executor service graceful at first, and then 
aggressively
@@ -302,10 +313,13 @@ public interface ExecutorServiceManager 
      * @param shutdownAwaitTermination timeout in millis to wait for orderly 
shutdown
      * @see java.util.concurrent.ExecutorService#shutdown()
      */
-    void shutdown(ExecutorService executorService, long 
shutdownAwaitTermination);
+    void shutdownGraceful(ExecutorService executorService, long 
shutdownAwaitTermination);
 
     /**
      * Shutdown now the given executor service aggressively.
+     * <p/>
+     * This implementation will issues a regular shutdownNow of the executor 
service,
+     * ie calling {@link java.util.concurrent.ExecutorService#shutdownNow()} 
and return.
      *
      * @param executorService the executor service to shutdown now
      * @return list of tasks that never commenced execution
@@ -313,4 +327,17 @@ public interface ExecutorServiceManager 
      */
     List<Runnable> shutdownNow(ExecutorService executorService);
 
+    /**
+     * Awaits the termination of the thread pool.
+     * <p/>
+     * This implementation will log every 2nd second at INFO level that we are 
waiting, so the end user
+     * can see we are not hanging in case it takes longer time to shutdown the 
pool.
+     *
+     * @param executorService            the thread pool
+     * @param shutdownAwaitTermination   time in millis to use as timeout
+     * @return <tt>true</tt> if the pool is terminated, or <tt>false</tt> if 
we timed out
+     * @throws InterruptedException is thrown if we are interrupted during 
waiting
+     */
+    boolean awaitTermination(ExecutorService executorService, long 
shutdownAwaitTermination) throws InterruptedException;
+
 }


Reply via email to