You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2014/08/02 08:12:28 UTC

git commit: fix effector queueing occasional bug where cross-context task may be queued already, and better javadoc and notes on cross-context executions

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 547b0e00e -> 9eccd5ba7


fix effector queueing occasional bug where cross-context task may be queued already, and better javadoc and notes on cross-context executions


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

Branch: refs/heads/master
Commit: 9eccd5ba739f99d65444a326cd3c087bf17c95b2
Parents: 547b0e0
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Sat Aug 2 02:11:02 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Sat Aug 2 02:11:38 2014 -0400

----------------------------------------------------------------------
 .../java/brooklyn/entity/basic/Entities.java    |  6 ++---
 .../util/task/AbstractExecutionContext.java     |  2 ++
 .../util/task/BasicExecutionContext.java        |  3 ++-
 .../java/brooklyn/util/task/CompoundTask.java   |  3 ++-
 .../util/task/DynamicSequentialTask.java        |  3 ++-
 .../java/brooklyn/util/task/DynamicTasks.java   |  4 +++-
 .../entity/group/DynamicClusterTest.java        | 24 ++++++++++++++++++++
 7 files changed, 38 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9eccd5ba/core/src/main/java/brooklyn/entity/basic/Entities.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/Entities.java b/core/src/main/java/brooklyn/entity/basic/Entities.java
index 3e8b225..8cca783 100644
--- a/core/src/main/java/brooklyn/entity/basic/Entities.java
+++ b/core/src/main/java/brooklyn/entity/basic/Entities.java
@@ -186,9 +186,9 @@ public class Entities {
         Task<T> t = Effectors.invocation(entityToCall, effector, parameters).asTask();
         TaskTags.markInessential(t);
         
-        // we pass to callingEntity for consistency above, but in exec-context it should be
-        // re-dispatched to targetEntity
-        ((EntityInternal)callingEntity).getManagementSupport().getExecutionContext().submit(
+        // we pass to callingEntity for consistency above, but in exec-context it should be re-dispatched to targetEntity
+        // reassign t as the return value may be a wrapper, if it is switching execution contexts; see submitInternal's javadoc
+        t = ((EntityInternal)callingEntity).getManagementSupport().getExecutionContext().submit(
                 MutableMap.of("tag", BrooklynTaskTags.tagForCallerEntity(callingEntity)), t);
         
         if (DynamicTasks.getTaskQueuingContext()!=null) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9eccd5ba/core/src/main/java/brooklyn/util/task/AbstractExecutionContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/AbstractExecutionContext.java b/core/src/main/java/brooklyn/util/task/AbstractExecutionContext.java
index 135a5ea..cd94915 100644
--- a/core/src/main/java/brooklyn/util/task/AbstractExecutionContext.java
+++ b/core/src/main/java/brooklyn/util/task/AbstractExecutionContext.java
@@ -63,6 +63,8 @@ public abstract class AbstractExecutionContext implements ExecutionContext {
      */
     public void execute(Runnable r) { submit(r); }
 
+    /** does the work internally of submitting the task; note that the return value may be a wrapper task even if a task is passed in,
+     * if the execution context where the target should run is different (e.g. submitting an effector task cross-context) */
     protected abstract <T> Task<T> submitInternal(Map<?,?> properties, Object task);
     
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9eccd5ba/core/src/main/java/brooklyn/util/task/BasicExecutionContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/BasicExecutionContext.java b/core/src/main/java/brooklyn/util/task/BasicExecutionContext.java
index 9663d29..a7bcbbd 100644
--- a/core/src/main/java/brooklyn/util/task/BasicExecutionContext.java
+++ b/core/src/main/java/brooklyn/util/task/BasicExecutionContext.java
@@ -131,7 +131,8 @@ public class BasicExecutionContext extends AbstractExecutionContext {
                     // when browsing in the context of the parent)
                     return submit(Tasks.<T>builder().name("Cross-context execution: "+t.getDescription()).dynamic(true).body(new Callable<T>() {
                         public T call() { 
-                            return DynamicTasks.get(t); }
+                            return DynamicTasks.get(t); 
+                        }
                     }).build());
                 } else {
                     // if we are already tracked by parent, just submit it 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9eccd5ba/core/src/main/java/brooklyn/util/task/CompoundTask.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/CompoundTask.java b/core/src/main/java/brooklyn/util/task/CompoundTask.java
index 9ca0915..b045e46 100644
--- a/core/src/main/java/brooklyn/util/task/CompoundTask.java
+++ b/core/src/main/java/brooklyn/util/task/CompoundTask.java
@@ -99,8 +99,9 @@ public abstract class CompoundTask<T> extends BasicTask<List<T>> implements HasT
             children.add(subtask);
         }
         
-        for (Task<?> t: getChildren())
+        for (Task<?> t: getChildren()) {
             ((TaskInternal<?>)t).markQueued();
+        }
     }
 
     /** return value needs to be specified by subclass; subclass should also setBlockingDetails 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9eccd5ba/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java b/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java
index 520c8b0..70fcc2a 100644
--- a/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java
+++ b/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java
@@ -40,6 +40,7 @@ import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.CountdownTimer;
 import brooklyn.util.time.Duration;
+import brooklyn.util.time.Time;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
@@ -137,7 +138,7 @@ public class DynamicSequentialTask<T> extends BasicTask<T> implements HasTaskChi
     public void queue(Task<?> t) {
         synchronized (jobTransitionLock) {
             if (primaryFinished)
-                throw new IllegalStateException("Cannot add a task to "+this+" when it is already finished (trying to add "+t+")");
+                throw new IllegalStateException("Cannot add a task to "+this+" which is already finished (trying to add "+t+")");
             secondaryJobsAll.add(t);
             secondaryJobsRemaining.add(t);
             BrooklynTaskTags.addTagsDynamically(t, ManagementContextInternal.SUB_TASK_TAG);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9eccd5ba/core/src/main/java/brooklyn/util/task/DynamicTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/DynamicTasks.java b/core/src/main/java/brooklyn/util/task/DynamicTasks.java
index c5c17c9..3d027c6 100644
--- a/core/src/main/java/brooklyn/util/task/DynamicTasks.java
+++ b/core/src/main/java/brooklyn/util/task/DynamicTasks.java
@@ -34,6 +34,7 @@ import brooklyn.management.TaskQueueingContext;
 import brooklyn.management.TaskWrapper;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.Duration;
+import brooklyn.util.time.Time;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
@@ -233,8 +234,9 @@ public class DynamicTasks {
             Preconditions.checkNotNull(task, "Task to queue cannot be null");
             Preconditions.checkState(!Tasks.isQueued(task), "Task to queue must not yet be queued: %s", task);
             TaskQueueingContext adder = getTaskQueuingContext();
-            if (adder==null) 
+            if (adder==null) {
                 throw new IllegalStateException("Task "+task+" cannot be queued here; no queueing context available");
+            }
             adder.queue(task.asTask());
             return task;
         } catch (Throwable e) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9eccd5ba/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java b/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
index 298d6d2..c862f8a 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
@@ -179,6 +179,30 @@ public class DynamicClusterTest extends BrooklynAppUnitTestSupport {
     }
 
     @Test
+    public void resizeDownByTwoAndDownByOne() throws Exception {
+        DynamicCluster cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure("factory", new EntityFactory() {
+                    @Override public Entity newEntity(Map flags, Entity parent) {
+                        return new TestEntityImpl(flags);
+                    }}));
+
+        cluster.start(ImmutableList.of(loc));
+
+        cluster.resize(4);
+        assertEquals(Iterables.size(Entities.descendants(cluster, TestEntity.class)), 4);
+        
+        // check delta of 2 and delta of 1, because >1 is handled differently to =1
+        cluster.resize(2);
+        assertEquals(Iterables.size(Entities.descendants(cluster, TestEntity.class)), 2);
+        cluster.resize(1);
+        assertEquals(Iterables.size(Entities.descendants(cluster, TestEntity.class)), 1);
+        cluster.resize(1);
+        assertEquals(Iterables.size(Entities.descendants(cluster, TestEntity.class)), 1);
+        cluster.resize(0);
+        assertEquals(Iterables.size(Entities.descendants(cluster, TestEntity.class)), 0);
+    }
+
+    @Test
     public void currentSizePropertyReflectsActualClusterSize() throws Exception {
         DynamicCluster cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
                 .configure("factory", new EntityFactory() {