Svet,

I think we need a code-change in Brooklyn to avoid having to do that Workaround.

---
Do you think we should:
    1. change `BrooklynGarbageCollector` so that a task will not be
        GC'ed if any of its child-tasks are non-transient?

Or do you think your use-case would be better met by either:

    2. ensuring your task is top-level (as per your workaround);
       e.g. something in the task-builder to mark it as top-level.
       or

    3. when GC'ing the parent task, promote non-transient child tasks to
       become top-level tasks (i.e. delete the parent, but not the child)?

I partly like (1), but it might be really ugly/confusing in the activities view if some poller tasks are shown and others are not.
(e.g. someone thinks that was the last time it polled).

Option (2) sounds good to support. I have a small worry it would get confusing though - e.g. for determining when the original task is completed, etc.

Option (3) sounds potentially dangerous if the tasks hierarchy has relationships between tasks. But all these tasks should have been completed; it's just the historic record we're talking about.

Thoughts?

Aled


On 16/03/2015 12:40, Svetoslav Neykov wrote:
If the parent task is transient, then the parent can be GC'ed, which will cause 
all its children to be GC'ed even if they are non-transient.
Yes, that's the case - I am submitting the task from a ScheduledTask started by 
a poller, so it's transient. I can't find a (good) way to make it non-GCable. 
The solution which I came up with doesn't look too good at all:

         Task<?> currentTask = 
BasicExecutionManager.getPerThreadCurrentTask().get();
         BasicExecutionManager.getPerThreadCurrentTask().set(null);
         try {
             Entities.submit(entity, updateService);
         } finally {
             BasicExecutionManager.getPerThreadCurrentTask().set(currentTask);
         }



I can see the task at the right place while placing a breakpoint in it, but as 
soon as it completes it is GCed at 
BrooklynGarbageCollector.expireSubTasksWhoseSubmitterIsExpired().

Svet.


On 16.03.2015 г., at 14:11, Aled Sage <[email protected]> wrote:

Svet,

I couldn't reproduce this. I wrote the following test, which passed:

    @Test
    public void testNonTransientTaskNotGced() throws Exception {
        Task<String> task = TaskBuilder.<String>builder()
                .body(Callables.returning("abc"))
.tag(BrooklynTaskTags.tagForContextEntity(app))
.tag(BrooklynTaskTags.NON_TRANSIENT_TASK_TAG)
                .build();
        Entities.submit(app, task);
        task.get();
((LocalManagementContext)mgmt).getGarbageCollector().gcIteration();

        Set<Task<?>> alltasks = app.getExecutionContext().getTasks();
        assertTrue(alltasks.contains(task));
    }

Could your task be not top-level perhaps? If the parent task is transient, then 
the parent can be GC'ed, which will cause all its children to be GC'ed even if 
they are non-transient.

Or could there be a lot of other tasks (it will by default only keep a max 
number of tasks per entity/tag, but it should delete the oldest tasks first).

Aled

p.s. the relevant code is 
`BrooklynGarbageCollector.shouldDeleteTaskImmediately`, which checks for the 
presence of the tag `ManagementContextInternal.NON_TRANSIENT_TASK_TAG`.


On 16/03/2015 11:46, Svetoslav Neykov wrote:
How do I create a top level task for an entity which remains after the current 
task completes?

I have code running in a poller which starts a task in certain conditions. I 
want the task to remain in the task list of the entity, but it is GCed after 
the ScheduledTaskcompletes and I see no way to prevent it.
I am starting the task as follows because I want it as a top-level task, 
instead of as a child of the current one.

TaskBuilder.builder()
                 .tag(BrooklynTaskTags.tagForContextEntity(entity))
                 .tag(BrooklynTaskTags.NON_TRANSIENT_TASK_TAG)
Entities.submit(entity, updateService);

Svet.


Reply via email to