You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@brooklyn.apache.org by Svetoslav Neykov <sv...@cloudsoftcorp.com> on 2015/03/16 12:46:27 UTC

Prevent task from being GCed?

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.

Re: Prevent task from being GCed?

Posted by Svetoslav Neykov <sv...@cloudsoftcorp.com>.
Aled,

What I need is option 2. I need to explicitly create a top-level task to be executed independently of the poller. In this case the poller task should be considered complete as soon as it returns. 

I think the way we treat transient currently is most natural - discard all children tasks as well, so Option 1 & 3 would be surprising. (1). would require all subtasks to be marked explicitly as transient which would be error-prone, (3) will create too much junk so better keep it hidden (or at least namespaced in a dummy task).  What I miss sometimes is to be able to check the isRunning script from UI though, would be nice to have it.

Svet.



> On 16.03.2015 г., at 15:08, Aled Sage <al...@gmail.com> wrote:
> 
> 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 <al...@gmail.com> 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.
>> 
> 


Re: Prevent task from being GCed?

Posted by Aled Sage <al...@gmail.com>.
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 <al...@gmail.com> 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.
>


Re: Prevent task from being GCed?

Posted by Svetoslav Neykov <sv...@cloudsoftcorp.com>.
>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 <al...@gmail.com> 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.
> 


Re: Prevent task from being GCed?

Posted by Aled Sage <al...@gmail.com>.
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.