@Override public String call(ConfigBag params) { switch (executionTarget) { case ENTITY: return callOne(params); case MEMBERS: return callMany(((Group)entity()).getMembers(), params); case CHILDREN: return callMany(entity().getChildren(), params); default: throw new IllegalStateException("Unknown value passed as execution target: " + executionTarget); } }
for (Entity child : entity.getChildren()) { builder.children.add(child.getId());
@Override public Void call(ConfigBag parameters) { Entity child = Iterables.getOnlyElement(entity().getChildren()); AtomicBoolean lock = new AtomicBoolean(); Task<Void> dummyTask = null; try { // Queue a (DST secondary) task which waits until notified, so that tasks queued later will get blocked queue(Effectors.invocation(entity(), STALL, ImmutableMap.of("lock", lock))); // Start a new task - submitted directly to child's ExecutionContext, as well as added as a // DST secondary of the current effector. dummyTask = child.invoke(DUMMY, ImmutableMap.<String, Object>of()); dummyTask.getUnchecked(); // Execution completed in the child's ExecutionContext, but still queued as a secondary. // Destroy the child entity so that no subsequent tasks can be executed in its context. Entities.destroy(child); } finally { // Let STALL complete synchronized(lock) { lock.set(true); lock.notifyAll(); } // At this point DUMMY will be unblocked and the DST will try to execute it as a secondary. // Submission will be ignored because DUMMY already executed. // If it's not ignored then submission will fail because entity is already unmanaged. } return null; } })
@Override public Integer call(ConfigBag parameters) { final Entity parent = entity(); final Entity child = Iterables.getOnlyElement(entity().getChildren()); final Effector<Integer> DOUBLE_CHECK_ABSTRACT = Effectors.effector(Integer.class, "double_check") .description("doubles the given number and checks tags, assuming double exists as an effector here") .parameter(Integer.class, "numberToDouble") .buildAbstract(); Effector<Integer> DOUBLE_CHECK = Effectors.effector(DOUBLE_CHECK_ABSTRACT) .impl(new EffectorBody<Integer>() { @Override public Integer call(ConfigBag parameters) { Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, null, false)); Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, DOUBLE_CHECK_ABSTRACT, false)); Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, DOUBLE_1, false)); Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, null, true)); Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, null, false)); Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, DOUBLE_CALL_ABSTRACT, true)); Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, DOUBLE_1, true)); return entity().invoke(DOUBLE_1, parameters.getAllConfig()).getUnchecked(); } }).build(); return child.invoke(DOUBLE_CHECK, parameters.getAllConfig()).getUnchecked(); } }).build();