brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rich...@apache.org
Subject [3/9] git commit: Adds BrooklynShutdownHooks.invokeTerminateOnShutdown(managementContext)
Date Tue, 27 May 2014 10:35:14 GMT
Adds BrooklynShutdownHooks.invokeTerminateOnShutdown(managementContext)

Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ab26150b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ab26150b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ab26150b

Branch: refs/heads/master
Commit: ab26150b5dc24494d6473cb88546e551493fe24f
Parents: a972f00
Author: Aled Sage <aled.sage@gmail.com>
Authored: Thu May 22 09:34:04 2014 +0100
Committer: Aled Sage <aled.sage@gmail.com>
Committed: Thu May 22 09:34:04 2014 +0100

----------------------------------------------------------------------
 .../entity/basic/BrooklynShutdownHooks.java     | 49 +++++++++++++++++---
 .../entity/basic/BrooklynShutdownHooksTest.java | 25 ++++++++++
 2 files changed, 67 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ab26150b/core/src/main/java/brooklyn/entity/basic/BrooklynShutdownHooks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/BrooklynShutdownHooks.java b/core/src/main/java/brooklyn/entity/basic/BrooklynShutdownHooks.java
index 979422b..928f918 100644
--- a/core/src/main/java/brooklyn/entity/basic/BrooklynShutdownHooks.java
+++ b/core/src/main/java/brooklyn/entity/basic/BrooklynShutdownHooks.java
@@ -9,8 +9,12 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.Entity;
 import brooklyn.entity.trait.Startable;
+import brooklyn.management.ManagementContext;
 import brooklyn.management.Task;
+import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.exceptions.RuntimeInterruptedException;
 import brooklyn.util.javalang.Threads;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -22,11 +26,23 @@ public class BrooklynShutdownHooks {
 
     private static final AtomicBoolean isShutdownHookRegistered = new AtomicBoolean();
     private static final List<Entity> entitiesToStopOnShutdown = Lists.newArrayList();
+    private static final List<ManagementContextInternal> managementContextsToTermianteOnShutdown
= Lists.newArrayList();
 
     public static void invokeStopOnShutdown(Entity entity) {
         synchronized (entitiesToStopOnShutdown) {
             entitiesToStopOnShutdown.add(entity);
         }
+        addShutdownHookIfNotAlready();
+    }
+    
+    public static void invokeTerminateOnShutdown(ManagementContext managementContext) {
+        synchronized (entitiesToStopOnShutdown) {
+            managementContextsToTermianteOnShutdown.add((ManagementContextInternal) managementContext);
+        }
+        addShutdownHookIfNotAlready();
+    }
+
+    private static void addShutdownHookIfNotAlready() {
         if (isShutdownHookRegistered.compareAndSet(false, true)) {
             Threads.addShutdownHook(new BrooklynShutdownHookJob());
         }
@@ -37,21 +53,40 @@ public class BrooklynShutdownHooks {
         @SuppressWarnings({ "unchecked", "rawtypes" })
         @Override
         public void run() {
+            // First stop entities; on interrupt, abort waiting for tasks - but let shutdown
hook continue
             synchronized (entitiesToStopOnShutdown) {
-                log.info("Brooklyn stopOnShutdown shutdown-hook invoked: stopping "+entitiesToStopOnShutdown);
+                log.info("Brooklyn stopOnShutdown shutdown-hook invoked: stopping entities:
"+entitiesToStopOnShutdown);
                 List<Task> stops = new ArrayList<Task>();
                 for (Entity entity: entitiesToStopOnShutdown) {
                     try {
                         stops.add(entity.invoke(Startable.STOP, new MutableMap()));
-                    } catch (Exception exc) {
-                        log.debug("stopOnShutdown of "+entity+" returned error: "+exc, exc);
+                    } catch (RuntimeException exc) {
+                        log.debug("stopOnShutdown of "+entity+" returned error (continuing):
"+exc, exc);
+                    }
+                }
+                try {
+                    for (Task t: stops) {
+                        try {
+                            log.debug("stopOnShutdown of {} completed: {}", t, t.get());
+                        } catch (Exception e) {
+                            log.debug("stopOnShutdown of "+t+" returned error (continuing):
"+e, e);
+                            Exceptions.propagateIfFatal(e);
+                        }
                     }
+                } catch (RuntimeInterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    log.debug("stopOnShutdown interrupted while waiting for entity-stop tasks;
continuing: "+e);
                 }
-                for (Task t: stops) {
+            }
+            
+            // Then terminate management contexts
+            synchronized (managementContextsToTermianteOnShutdown) {
+                log.info("Brooklyn terminateOnShutdown shutdown-hook invoked: terminating
management contexts: "+managementContextsToTermianteOnShutdown);
+                for (ManagementContextInternal managementContext: managementContextsToTermianteOnShutdown)
{
                     try {
-                        log.debug("stopOnShutdown of {} completed: {}", t, t.get());
-                    } catch (Exception exc) {
-                        log.debug("stopOnShutdown of "+t+" returned error: "+exc, exc);
+                        managementContext.terminate();
+                    } catch (RuntimeException e) {
+                        log.info("terminateOnShutdown of "+managementContext+" returned error
(continuing): "+e, e);
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ab26150b/core/src/test/java/brooklyn/entity/basic/BrooklynShutdownHooksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/BrooklynShutdownHooksTest.java b/core/src/test/java/brooklyn/entity/basic/BrooklynShutdownHooksTest.java
index ba65f46..7961cf6 100644
--- a/core/src/test/java/brooklyn/entity/basic/BrooklynShutdownHooksTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/BrooklynShutdownHooksTest.java
@@ -1,5 +1,6 @@
 package brooklyn.entity.basic;
 
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
 import org.testng.annotations.AfterMethod;
@@ -7,11 +8,13 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.management.ManagementContext;
 import brooklyn.test.entity.TestApplication;
 import brooklyn.test.entity.TestEntity;
 
 public class BrooklynShutdownHooksTest {
 
+    private ManagementContext managementContext;
     private TestApplication app;
     private TestEntity entity;
     
@@ -19,6 +22,7 @@ public class BrooklynShutdownHooksTest {
     public void setUp() {
         app = ApplicationBuilder.newManagedApp(TestApplication.class);
         entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        managementContext = app.getManagementContext();
     }
     
     @AfterMethod(alwaysRun=true)
@@ -34,4 +38,25 @@ public class BrooklynShutdownHooksTest {
         
         assertTrue(entity.getCallHistory().contains("stop"));
     }
+    
+    @Test
+    public void testInvokeTerminateManagementContextOnShutdown() throws Exception {
+        BrooklynShutdownHooks.invokeTerminateOnShutdown(managementContext);
+        BrooklynShutdownHooks.BrooklynShutdownHookJob job = new BrooklynShutdownHooks.BrooklynShutdownHookJob();
+        job.run();
+        
+        assertFalse(managementContext.isRunning());
+    }
+
+    // Should first stop entities, then terminate management contexts
+    @Test
+    public void testInvokeStopEntityAndTerminateManagementContextOnShutdown() throws Exception
{
+        BrooklynShutdownHooks.invokeTerminateOnShutdown(managementContext);
+        BrooklynShutdownHooks.invokeStopOnShutdown(entity);
+        BrooklynShutdownHooks.BrooklynShutdownHookJob job = new BrooklynShutdownHooks.BrooklynShutdownHookJob();
+        job.run();
+        
+        assertTrue(entity.getCallHistory().contains("stop"));
+        assertFalse(managementContext.isRunning());
+    }
 }


Mime
View raw message