add overridable doStart to DynamicClusterImpl to facilitate custom logic to 
happen before expected state is RUNNING;
add a service problem-indicator rather than setting expected state ON_FIRE, and 
wait for queued tasks to complete before setting expected state RUNNING


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

Branch: refs/heads/master
Commit: f51710de18fad107810670d569cbe6efc68aa56f
Parents: df971f5
Author: Alex Heneveld <[email protected]>
Authored: Thu Aug 28 22:32:12 2014 -0400
Committer: Alex Heneveld <[email protected]>
Committed: Mon Sep 1 17:07:01 2014 +0100

----------------------------------------------------------------------
 .../entity/group/DynamicClusterImpl.java        | 126 ++++++++++---------
 1 file changed, 67 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f51710de/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java 
b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
index 553d453..647ddaa 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
@@ -36,12 +36,12 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.AbstractGroupImpl;
-import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.basic.EntityFactoryForLocation;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.QuorumCheck.QuorumChecks;
+import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.proxying.EntitySpec;
@@ -260,71 +260,79 @@ public class DynamicClusterImpl extends AbstractGroupImpl 
implements DynamicClus
         }
 
         ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
+        ServiceProblemsLogic.clearProblemsIndicator(this, START);
         try {
-            if (isQuarantineEnabled()) {
-                QuarantineGroup quarantineGroup = 
getAttribute(QUARANTINE_GROUP);
-                if (quarantineGroup==null || 
!Entities.isManaged(quarantineGroup)) {
-                    quarantineGroup = 
addChild(EntitySpec.create(QuarantineGroup.class).displayName("quarantine"));
-                    Entities.manage(quarantineGroup);
-                    setAttribute(QUARANTINE_GROUP, quarantineGroup);
-                }
-            }
-
-            int initialSize = getConfig(INITIAL_SIZE).intValue();
-            int initialQuorumSize = getInitialQuorumSize();
+            doStart();
+            DynamicTasks.waitForLast();
+            
+        } catch (Exception e) {
+            ServiceProblemsLogic.updateProblemsIndicator(this, START, "start 
failed with error: "+e);
+            throw Exceptions.propagate(e);
+        } finally {
+            ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
+        }
+    }
 
-            try {
-                resize(initialSize);
-            } catch (Exception e) {
-                Exceptions.propagateIfFatal(e);
-                // apart from logging, ignore problems here; we extract them 
below
-                LOG.debug("Error resizing "+this+" to size "+initialSize+" 
(collecting and handling): "+e, e);
+    protected void doStart() {
+        if (isQuarantineEnabled()) {
+            QuarantineGroup quarantineGroup = getAttribute(QUARANTINE_GROUP);
+            if (quarantineGroup==null || !Entities.isManaged(quarantineGroup)) 
{
+                quarantineGroup = 
addChild(EntitySpec.create(QuarantineGroup.class).displayName("quarantine"));
+                Entities.manage(quarantineGroup);
+                setAttribute(QUARANTINE_GROUP, quarantineGroup);
             }
+        }
 
-            Iterable<Task<?>> failed = 
Tasks.failed(Tasks.children(Tasks.current()));
-            Iterator<Task<?>> fi = failed.iterator();
-            boolean noFailed=true, severalFailed=false;
-            if (fi.hasNext()) {
-                noFailed = false;
-                fi.next();
-                if (fi.hasNext())
-                    severalFailed = true;
-            }
+        int initialSize = getConfig(INITIAL_SIZE).intValue();
+        int initialQuorumSize = getInitialQuorumSize();
 
-            int currentSize = getCurrentSize().intValue();
-            if (currentSize < initialQuorumSize) {
-                String message;
-                if (currentSize == 0 && !noFailed) {
-                    if (severalFailed)
-                        message = "All nodes in cluster "+this+" failed";
-                    else
-                        message = "Node in cluster "+this+" failed";
-                } else {
-                    message = "On start of cluster " + this + ", failed to get 
to initial size of " + initialSize
-                        + "; size is " + getCurrentSize()
-                        + (initialQuorumSize != initialSize ? " (initial 
quorum size is " + initialQuorumSize + ")" : "");
-                }
-                Throwable firstError = 
Tasks.getError(Maybe.next(failed.iterator()).orNull());
-                if (firstError!=null) {
-                    if (severalFailed)
-                        message += "; first failure is: 
"+Exceptions.collapseText(firstError);
-                    else
-                        message += ": "+Exceptions.collapseText(firstError);
-                }
-                throw new IllegalStateException(message, firstError);
-            } else if (currentSize < initialSize) {
-                LOG.warn(
-                        "On start of cluster {}, size {} reached initial 
minimum quorum size of {} but did not reach desired size {}; continuing",
-                        new Object[] { this, currentSize, initialQuorumSize, 
initialSize });
+        try {
+            resize(initialSize);
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            // apart from logging, ignore problems here; we extract them below
+            LOG.debug("Error resizing "+this+" to size "+initialSize+" 
(collecting and handling): "+e, e);
+        }
+
+        Iterable<Task<?>> failed = 
Tasks.failed(Tasks.children(Tasks.current()));
+        Iterator<Task<?>> fi = failed.iterator();
+        boolean noFailed=true, severalFailed=false;
+        if (fi.hasNext()) {
+            noFailed = false;
+            fi.next();
+            if (fi.hasNext())
+                severalFailed = true;
+        }
+
+        int currentSize = getCurrentSize().intValue();
+        if (currentSize < initialQuorumSize) {
+            String message;
+            if (currentSize == 0 && !noFailed) {
+                if (severalFailed)
+                    message = "All nodes in cluster "+this+" failed";
+                else
+                    message = "Node in cluster "+this+" failed";
+            } else {
+                message = "On start of cluster " + this + ", failed to get to 
initial size of " + initialSize
+                    + "; size is " + getCurrentSize()
+                    + (initialQuorumSize != initialSize ? " (initial quorum 
size is " + initialQuorumSize + ")" : "");
             }
-
-            for (Policy it : getPolicies()) {
-                it.resume();
+            Throwable firstError = 
Tasks.getError(Maybe.next(failed.iterator()).orNull());
+            if (firstError!=null) {
+                if (severalFailed)
+                    message += "; first failure is: 
"+Exceptions.collapseText(firstError);
+                else
+                    message += ": "+Exceptions.collapseText(firstError);
             }
-            ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
-        } catch (Exception e) {
-            ServiceStateLogic.setExpectedState(this, Lifecycle.ON_FIRE);
-            throw Exceptions.propagate(e);
+            throw new IllegalStateException(message, firstError);
+        } else if (currentSize < initialSize) {
+            LOG.warn(
+                    "On start of cluster {}, size {} reached initial minimum 
quorum size of {} but did not reach desired size {}; continuing",
+                    new Object[] { this, currentSize, initialQuorumSize, 
initialSize });
+        }
+
+        for (Policy it : getPolicies()) {
+            it.resume();
         }
     }
 

Reply via email to