Fix BrooklynNode unmanage - wait for parent tasks to complete
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/fcaa205f Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/fcaa205f Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/fcaa205f Branch: refs/heads/master Commit: fcaa205f95dacc039e6905a6a1bf729d9f8f45f5 Parents: af9cf33 Author: Svetoslav Neykov <[email protected]> Authored: Thu Jun 25 21:53:22 2015 +0300 Committer: Svetoslav Neykov <[email protected]> Committed: Thu Jun 25 21:53:22 2015 +0300 ---------------------------------------------------------------------- .../entity/brooklynnode/BrooklynNodeImpl.java | 22 ++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fcaa205f/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java ---------------------------------------------------------------------- diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java index e4ca6c5..017a19d 100644 --- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java +++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java @@ -225,12 +225,26 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod protected void postStop() { super.postStop(); if (isMachineStopped()) { - // Don't unmanage in entity's task context as it will self-cancel the task. Wait for the stop effector to complete. + // Don't unmanage in entity's task context as it will self-cancel the task. Wait for the stop effector to complete (and all parent entity tasks). // If this is not enough (still getting Caused by: java.util.concurrent.CancellationException: null) then - // we could search for the top most task with entity context == this and wait on it. Even stronger would be - // to wait for BrooklynTaskTags.getTasksInEntityContext(ExecutionManager, this).isEmpty(); + // we could wait for BrooklynTaskTags.getTasksInEntityContext(ExecutionManager, this).isEmpty(); Task<?> stopEffectorTask = BrooklynTaskTags.getClosestEffectorTask(Tasks.current(), Startable.STOP); - getManagementContext().getExecutionManager().submit(new UnmanageTask(stopEffectorTask, this)); + Task<?> topEntityTask = getTopEntityTask(stopEffectorTask); + getManagementContext().getExecutionManager().submit(new UnmanageTask(topEntityTask, this)); + } + } + + private Task<?> getTopEntityTask(Task<?> stopEffectorTask) { + Entity context = BrooklynTaskTags.getContextEntity(stopEffectorTask); + Task<?> topTask = stopEffectorTask; + while (true) { + Task<?> parentTask = topTask.getSubmittedByTask(); + Entity parentContext = BrooklynTaskTags.getContextEntity(parentTask); + if (parentTask == null || parentContext != context) { + return topTask; + } else { + topTask = parentTask; + } } }
