You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/03/16 12:58:06 UTC

[camel-spring-boot] 03/03: CAMEL-14642: camel-spring-boot - Using max duration and shutdown before should terminate scheduled thread quicker

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git

commit 8ec796b7e3cc0064677ff23b3b4e16d080232c7e
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Mar 16 13:57:50 2020 +0100

    CAMEL-14642: camel-spring-boot - Using max duration and shutdown before should terminate scheduled thread quicker
---
 .../boot/CamelSpringBootApplicationListener.java   | 60 ++++++++++++++++------
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelSpringBootApplicationListener.java b/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelSpringBootApplicationListener.java
index 9942705..8f6c5d0 100644
--- a/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelSpringBootApplicationListener.java
+++ b/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelSpringBootApplicationListener.java
@@ -220,16 +220,24 @@ public class CamelSpringBootApplicationListener implements ApplicationListener<C
 
     private void terminateMainControllerAfter(final CamelContext camelContext, int seconds, final AtomicBoolean completed, final CountDownLatch latch) {
         ScheduledExecutorService executorService = camelContext.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, "CamelSpringBootTerminateTask");
+
+        final AtomicBoolean running = new AtomicBoolean();
         Runnable task = () -> {
-            LOG.info("CamelSpringBoot triggering shutdown of the JVM.");
-            try {
-                camelContext.stop();
-            } catch (Throwable e) {
-                LOG.warn("Error during stopping CamelContext", e);
-            } finally {
-                completed.set(true);
-                latch.countDown();
-            }
+            // need to spin up as separate thread so we can terminate this thread pool without problems
+            Runnable stop = () -> {
+                running.set(true);
+                LOG.info("CamelSpringBoot triggering shutdown of the JVM.");
+                try {
+                    camelContext.stop();
+                } catch (Throwable e) {
+                    LOG.warn("Error during stopping CamelContext", e);
+                } finally {
+                    completed.set(true);
+                    latch.countDown();
+                }
+                running.set(false);
+            };
+            new Thread(stop, "CamelSpringBootTerminateTaskWorker").start();
         };
 
         final ScheduledFuture future = executorService.schedule(task, seconds, TimeUnit.SECONDS);
@@ -237,17 +245,27 @@ public class CamelSpringBootApplicationListener implements ApplicationListener<C
             @Override
             public void onContextStop(CamelContext context) {
                 // we are stopping then cancel the task so we can shutdown quicker
-                future.cancel(true);
+                if (!running.get()) {
+                    future.cancel(true);
+                }
             }
         });
     }
 
     private void terminateApplicationContext(final ConfigurableApplicationContext applicationContext, final CamelContext camelContext, int seconds) {
         ScheduledExecutorService executorService = camelContext.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, "CamelSpringBootTerminateTask");
+
+        final AtomicBoolean running = new AtomicBoolean();
         Runnable task = () -> {
-            LOG.info("CamelSpringBoot triggering shutdown of the JVM.");
-            // we need to run a daemon thread to stop ourselves so this thread pool can be stopped nice also
-            new Thread(applicationContext::close).start();
+            // need to spin up as separate thread so we can terminate this thread pool without problems
+            Runnable stop = () -> {
+                running.set(true);
+                LOG.info("CamelSpringBoot triggering shutdown of the JVM.");
+                // we need to run a daemon thread to stop ourselves so this thread pool can be stopped nice also
+                new Thread(applicationContext::close).start();
+                running.set(false);
+            };
+            new Thread(stop, "CamelSpringBootTerminateTaskWorker").start();
         };
 
         final ScheduledFuture future = executorService.schedule(task, seconds, TimeUnit.SECONDS);
@@ -255,22 +273,29 @@ public class CamelSpringBootApplicationListener implements ApplicationListener<C
             @Override
             public void onContextStop(CamelContext context) {
                 // we are stopping then cancel the task so we can shutdown quicker
-                future.cancel(true);
+                if (!running.get()) {
+                    future.cancel(true);
+                }
             }
         });
     }
 
     private void terminateApplicationContext(final ConfigurableApplicationContext applicationContext, final CamelContext camelContext, final CountDownLatch latch) {
         ExecutorService executorService = camelContext.getExecutorServiceManager().newSingleThreadExecutor(this, "CamelSpringBootTerminateTask");
+
+        final AtomicBoolean running = new AtomicBoolean();
         Runnable task = () -> {
             try {
                 latch.await();
+                // only mark as running after the latch
+                running.set(true);
                 LOG.info("CamelSpringBoot triggering shutdown of the JVM.");
                 // we need to run a daemon thread to stop ourselves so this thread pool can be stopped nice also
                 new Thread(applicationContext::close).start();
             } catch (Throwable e) {
                 // ignore
             }
+            running.set(false);
         };
 
         final Future future = executorService.submit(task);
@@ -278,7 +303,12 @@ public class CamelSpringBootApplicationListener implements ApplicationListener<C
             @Override
             public void onContextStop(CamelContext context) {
                 // we are stopping then cancel the task so we can shutdown quicker
-                future.cancel(true);
+                if (!running.get()) {
+                    future.cancel(true);
+                } else {
+                    // trigger shutdown
+                    latch.countDown();
+                }
             }
         });
     }