Merge pull request #1163 from ahgittin/better-task-stop-logic
don't interrupt tasks related to a deletion/unmanagement
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BrooklynGarbageCollector.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BrooklynGarbageCollector.java
index 48ead9d..a48f1f0 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BrooklynGarbageCollector.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BrooklynGarbageCollector.java
@@ -278,6 +278,7 @@
public void deleteTasksForEntity(Entity entity) {
// remove all references to this entity from tasks
+ // (note that cancellation for most tasks will have been done by LocalEntityManager.stopTasks)
executionManager.deleteTag(entity);
executionManager.deleteTag(BrooklynTaskTags.tagForContextEntity(entity));
executionManager.deleteTag(BrooklynTaskTags.tagForCallerEntity(entity));
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java
index 92abbe4..bd8ea5b 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java
@@ -594,13 +594,25 @@
// try forcibly interrupting tasks on managed entities
Collection<Exception> exceptions = MutableSet.of();
try {
+ boolean inTaskForThisEntity = entity.equals(BrooklynTaskTags.getContextEntity(Tasks.current()));
+ Task rootTask = null;
Set<Task<?>> tasksCancelled = MutableSet.of();
for (Task<?> t: managementContext.getExecutionContext(entity).getTasks()) {
- if (entity.equals(BrooklynTaskTags.getContextEntity(Tasks.current())) && hasTaskAsAncestor(t, Tasks.current())) {
- // don't cancel if we are running inside a task on the target entity and
- // the task being considered is one we have submitted -- e.g. on "stop" don't cancel ourselves!
- // but if our current task is from another entity we probably do want to cancel them (we are probably invoking unmanage)
- continue;
+ if (inTaskForThisEntity) {
+ if (rootTask==null) {
+ rootTask = getRootTask(Tasks.current());
+ }
+ if (Objects.equals(rootTask, getRootTask(t))) {
+ // don't cancel the task if:
+ // - the current task is against this entity, and
+ // - the current task and target task are part of the same root true
+ // e.g. on "stop" don't cancel ourselves, don't cancel things our ancestors have submitted
+ // (direct ancestry check is not good enough, because we might be in a subtask of a deletion which has a DST manager,
+ // and cancelling the DST manager is almost as bad as cancelling ourselves);
+ // however if our current task is from another entity we maybe do want to cancel other things running at this node
+ // (although maybe not; we could remote the "inTaskForThisEntity" check)
+ continue;
+ }
}
if (!t.isDone()) {
@@ -650,6 +662,15 @@
return hasTaskAsAncestor(t.getSubmittedByTask(), potentialAncestor);
}
+ private Task<?> getRootTask(Task<?> t) {
+ Task<?> result = t;
+ while (t!=null) {
+ result = t;
+ t = t.getSubmittedByTask();
+ }
+ return result;
+ }
+
/**
* activates management when effector invoked, warning unless context is acceptable
* (currently only acceptable context is "start")