Repository: brooklyn-server
Updated Branches:
  refs/heads/master d85ffa5b4 -> d73a91d17


remove FIRST_MEMBER sensor, it doesn't work, and deprecate FIRST

both are a bit flaky, but FIRST_MEMBER especially so:
it would never get cleared, and it could cause deadlock
(as parent attempts to update child's sensor while holding members lock,
meanwhile child might publish a sensor which causes parent subscriber to try to 
getMembers).

additionally we no longer set FIRST=(other entity) on the child, for the same 
reasons,
but also it causes conflict if the child is also a group (so FIRST might be the 
parent's FIRST
or its own FIRST).

the new "primary" model is a much better one to use instead when you need 
notification
of something being promoted, or an enricher if you need the parent's first 
injected locally
(but you should always be able to say 
`$brooklyn:parent().attributeWhenReady("first"))`)


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

Branch: refs/heads/master
Commit: e8d25ca95a43af52c0c8a97e2da1c707f9d7fa68
Parents: b2251f4
Author: Alex Heneveld <[email protected]>
Authored: Mon Jul 24 17:01:51 2017 +0100
Committer: Alex Heneveld <[email protected]>
Committed: Mon Jul 24 17:08:24 2017 +0100

----------------------------------------------------------------------
 .../apache/brooklyn/entity/group/AbstractGroup.java  | 14 +++++++++-----
 .../brooklyn/entity/group/AbstractGroupImpl.java     | 15 +++------------
 .../brooklyn/entity/group/DynamicClusterImpl.java    |  2 +-
 .../brooklyn/entity/group/DynamicClusterTest.java    |  2 +-
 4 files changed, 14 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e8d25ca9/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java 
b/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java
index 625d981..66d2d89 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java
@@ -50,11 +50,9 @@ public interface AbstractGroup extends Entity, Group, 
Changeable {
     AttributeSensor<Collection<Entity>> GROUP_MEMBERS = Sensors.newSensor(
             new TypeToken<Collection<Entity>>() { }, "group.members", "Members 
of the group");
 
-    // FIXME should definitely remove this, it is ambiguous if an entity is in 
multiple clusters.  also should be "is_first" or something to indicate boolean.
-    AttributeSensor<Boolean> FIRST_MEMBER = Sensors.newBooleanSensor(
-            "cluster.first", "Set on an entity if it is the first member of a 
cluster");
-
-    // FIXME can we remove this too?
+    /** @deprecated since 0.12.0 use AbstractGroup.getFirst(Group) if required,
+     * or better use an external enricher or policy to define the primary. */
+    @Deprecated
     AttributeSensor<Entity> FIRST = Sensors.newSensor(Entity.class,
             "cluster.first.entity", "The first member of the cluster");
 
@@ -87,4 +85,10 @@ public interface AbstractGroup extends Entity, Group, 
Changeable {
     // FIXME Do we really want this method? "setMembers" is a misleading name
     void setMembers(Collection<Entity> mm, Predicate<Entity> filter);
 
+    public static Entity getFirst(Group g) {
+        Collection<Entity> members = 
g.sensors().get(AbstractGroup.GROUP_MEMBERS);
+        if (!members.isEmpty()) return members.iterator().next();
+        return null;
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e8d25ca9/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroupImpl.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroupImpl.java 
b/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroupImpl.java
index 23fb921..81f6da4 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroupImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroupImpl.java
@@ -107,16 +107,7 @@ public abstract class AbstractGroupImpl extends 
AbstractEntity implements Abstra
                 // FIXME do not set sensors on members; possibly we don't need 
FIRST at all, just look at the first in MEMBERS, and take care to guarantee 
order there
                 Entity first = getAttribute(FIRST);
                 if (first == null) {
-                    member.sensors().set(FIRST_MEMBER, true);
-                    member.sensors().set(FIRST, member);
                     sensors().set(FIRST, member);
-                } else {
-                    if (first.equals(member) || 
first.equals(member.getAttribute(FIRST))) {
-                        // do nothing (rebinding)
-                    } else {
-                        member.sensors().set(FIRST_MEMBER, false);
-                        member.sensors().set(FIRST, first);
-                    }
                 }
     
                 
((EntityInternal)member).groups().add((Group)getProxyIfAvailable());
@@ -165,10 +156,10 @@ public abstract class AbstractGroupImpl extends 
AbstractEntity implements Abstra
                     log.debug("Group {} lost member {}", this, member);
                     // TODO ideally the following are all synched
                     sensors().set(GROUP_SIZE, getCurrentSize());
-                    sensors().set(GROUP_MEMBERS, getMembers());
+                    Collection<Entity> membersNow = getMembers();
+                    sensors().set(GROUP_MEMBERS, membersNow);
                     if (member.equals(getAttribute(FIRST))) {
-                        // TODO should we elect a new FIRST ?  as is the 
*next* will become first.  could we do away with FIRST altogether?
-                        sensors().set(FIRST, null);
+                        sensors().set(FIRST, membersNow.isEmpty() ? null : 
membersNow.iterator().next());
                     }
                     // emit after the above so listeners can use getMembers() 
and getCurrentSize()
                     sensors().emit(MEMBER_REMOVED, member);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e8d25ca9/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java 
b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
index 03eec38..0b2ec02 100644
--- 
a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
+++ 
b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
@@ -847,7 +847,7 @@ public class DynamicClusterImpl extends AbstractGroupImpl 
implements DynamicClus
             if (entity instanceof Startable) {
                 // First members are used when subsequent members need some 
attributes from them
                 // before they start; make sure they're in the first batch.
-                boolean privileged = 
Boolean.TRUE.equals(entity.sensors().get(AbstractGroup.FIRST_MEMBER));
+                boolean privileged = 
entity.equals(AbstractGroup.getFirst(this));
                 Map<String, ?> args = ImmutableMap.of("locations", 
MutableList.builder().addIfNotNull(loc).buildImmutable());
                 Task<?> task = newThrottledEffectorTask(entity, 
Startable.START, args, privileged);
                 tasks.put(entity, task);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e8d25ca9/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java 
b/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java
index 5b76bbc..f4a303d 100644
--- 
a/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/entity/group/DynamicClusterTest.java
@@ -1255,7 +1255,7 @@ public class DynamicClusterTest extends 
AbstractDynamicClusterOrFabricTest {
         public void start(Collection<? extends Location> locs) {
             int count = config().get(COUNTER).incrementAndGet();
             try {
-                LOG.debug("{} starting (first={})", new Object[]{this, 
sensors().get(AbstractGroup.FIRST_MEMBER)});
+                LOG.debug("{} starting (members={})", new Object[]{this, 
getParent().sensors().get(AbstractGroup.GROUP_MEMBERS)});
                 config().get(START_LATCH);
                 // Throw if more than one entity is starting at the same time 
as this.
                 assertTrue(count <= config().get(MAX_CONCURRENCY), "expected " 
+ count + " <= " + config().get(MAX_CONCURRENCY));

Reply via email to