Github user aledsage commented on a diff in the pull request:
https://github.com/apache/brooklyn-server/pull/816#discussion_r141917699
--- Diff:
core/src/main/java/org/apache/brooklyn/util/core/task/BasicExecutionContext.java
---
@@ -110,48 +248,53 @@ public ExecutionManager getExecutionManager() {
@SuppressWarnings("unchecked")
@Override
public <T> Maybe<T> getImmediately(Object callableOrSupplier) {
- BasicTask<?> fakeTaskForContext;
+ BasicTask<T> fakeTaskForContext;
if (callableOrSupplier instanceof BasicTask) {
- fakeTaskForContext = (BasicTask<?>)callableOrSupplier;
+ fakeTaskForContext = (BasicTask<T>)callableOrSupplier;
if (fakeTaskForContext.isQueuedOrSubmitted()) {
if (fakeTaskForContext.isDone()) {
- return Maybe.of((T)fakeTaskForContext.getUnchecked());
+ return Maybe.of(fakeTaskForContext.getUnchecked());
} else {
throw new ImmediateUnsupportedException("Task is in
progress and incomplete: "+fakeTaskForContext);
}
}
callableOrSupplier = fakeTaskForContext.getJob();
+ } else if (callableOrSupplier instanceof TaskAdaptable) {
+ return getImmediately(
((TaskAdaptable<T>)callableOrSupplier).asTask() );
} else {
- fakeTaskForContext = new
BasicTask<Object>(MutableMap.of("displayName", "immediate evaluation"));
+ fakeTaskForContext = new
BasicTask<T>(MutableMap.of("displayName", "Immediate evaluation"));
}
- fakeTaskForContext.tags.addAll(tags);
+ final ImmediateSupplier<T> job = callableOrSupplier instanceof
ImmediateSupplier ? (ImmediateSupplier<T>) callableOrSupplier
+ : InterruptingImmediateSupplier.<T>of(callableOrSupplier);
fakeTaskForContext.tags.add(BrooklynTaskTags.IMMEDIATE_TASK_TAG);
fakeTaskForContext.tags.add(BrooklynTaskTags.TRANSIENT_TASK_TAG);
-
- Task<?> previousTask =
BasicExecutionManager.getPerThreadCurrentTask().get();
- BasicExecutionContext oldExecutionContext =
getCurrentExecutionContext();
- registerPerThreadExecutionContext();
- if (previousTask!=null)
fakeTaskForContext.setSubmittedByTask(previousTask);
- fakeTaskForContext.cancel();
+ ContextSwitchingInfo<T> switchContextWrapper =
getContextSwitchingTask(fakeTaskForContext, Collections.emptyList(), true);
+ if (switchContextWrapper!=null) {
+ return
switchContextWrapper.context.getImmediately(switchContextWrapper.wrapperTask);
+ }
+
try {
-
BasicExecutionManager.getPerThreadCurrentTask().set(fakeTaskForContext);
-
- if (!(callableOrSupplier instanceof ImmediateSupplier)) {
- callableOrSupplier =
InterruptingImmediateSupplier.of(callableOrSupplier);
- }
- boolean wasAlreadyInterrupted = Thread.interrupted();
- try {
- return
((ImmediateSupplier<T>)callableOrSupplier).getImmediately();
- } finally {
- if (wasAlreadyInterrupted) {
- Thread.currentThread().interrupt();
- }
- }
-
- } finally {
-
BasicExecutionManager.getPerThreadCurrentTask().set(previousTask);
- perThreadExecutionContext.set(oldExecutionContext);
+ return runInSameThread(fakeTaskForContext, new
Callable<Maybe<T>>() {
--- End diff --
Yeah. It was sort-of-safe in
https://github.com/apache/brooklyn-server/commit/49f0e225f8196c9d2314afe52cffbc1839cdfcf6
because we were always creating a new task object, which we were cancelling.
But then in
https://github.com/apache/brooklyn-server/commit/cd3d4864aa2a59a18f28997313ca07bc9185fd62
it was changed to sometimes re-use the task that was passed in.
---