-
Notifications
You must be signed in to change notification settings - Fork 53
Config self reference fix #480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d7c6036
4121554
5324f82
a679682
faeeb1b
f84d886
49f0e22
72eff85
3f3e3d6
7476d3b
b073349
0aa29ef
cd3d486
99ccc0f
2e6f11f
4602114
a3f42d3
e6fd10c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,10 +41,13 @@ | |
| import org.apache.brooklyn.core.mgmt.BrooklynTaskTags.WrappedEntity; | ||
| import org.apache.brooklyn.core.mgmt.entitlement.Entitlements; | ||
| import org.apache.brooklyn.util.collections.MutableMap; | ||
| import org.apache.brooklyn.util.core.task.ImmediateSupplier.ImmediateUnsupportedException; | ||
| import org.apache.brooklyn.util.guava.Maybe; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| import com.google.common.base.Function; | ||
| import com.google.common.base.Supplier; | ||
| import com.google.common.collect.Iterables; | ||
|
|
||
| /** | ||
|
|
@@ -96,7 +99,55 @@ public ExecutionManager getExecutionManager() { | |
| /** returns tasks started by this context (or tasks which have all the tags on this object) */ | ||
| @Override | ||
| public Set<Task<?>> getTasks() { return executionManager.getTasksWithAllTags(tags); } | ||
|
|
||
|
|
||
| /** performs execution without spawning a new task thread, though it does temporarily set a fake task for the purpose of getting context; | ||
| * currently supports {@link Supplier}, {@link Callable}, {@link Runnable}, or {@link Task} instances; | ||
| * with tasks if it is submitted or in progress, | ||
| * it fails if not completed; with unsubmitted, unqueued tasks, it gets the {@link Callable} job and | ||
| * uses that; with such a job, or any other callable/supplier/runnable, it runs that | ||
| * in an {@link InterruptingImmediateSupplier}, with as much metadata as possible (eg task name if | ||
| * given a task) set <i>temporarily</i> in the current thread context */ | ||
| @SuppressWarnings("unchecked") | ||
| @Override | ||
| public <T> Maybe<T> getImmediately(Object callableOrSupplier) { | ||
| BasicTask<?> fakeTaskForContext; | ||
| if (callableOrSupplier instanceof BasicTask) { | ||
| fakeTaskForContext = (BasicTask<?>)callableOrSupplier; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Under what code path do we get here? Looking at For example, the test below fails (added to I'm not convinced that we want to support setting a config key with a value of type
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as noted above leaving the task running in background (or possibly not submitting it) is the right thing to do for immediate execution of a task; cancelling it is risky unless we know the task is dedicated to this one usage (hence preferring
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As for the particular code block marked here, it is invoked from |
||
| if (fakeTaskForContext.isQueuedOrSubmitted()) { | ||
| if (fakeTaskForContext.isDone()) { | ||
| return Maybe.of((T)fakeTaskForContext.getUnchecked()); | ||
| } else { | ||
| throw new ImmediateUnsupportedException("Task is in progress and incomplete: "+fakeTaskForContext); | ||
| } | ||
| } | ||
| callableOrSupplier = fakeTaskForContext.getJob(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very clever, getting the underlying However, I wonder if this just reduces the chance of leaving tasks behind (rather than preventing it). The test below fails when added to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as above |
||
| } else { | ||
| fakeTaskForContext = new BasicTask<Object>(MutableMap.of("displayName", "immediate evaluation")); | ||
| } | ||
| fakeTaskForContext.tags.addAll(tags); | ||
| 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(); | ||
| try { | ||
| BasicExecutionManager.getPerThreadCurrentTask().set(fakeTaskForContext); | ||
|
|
||
| if (!(callableOrSupplier instanceof ImmediateSupplier)) { | ||
| callableOrSupplier = InterruptingImmediateSupplier.of(callableOrSupplier); | ||
| } | ||
| return ((ImmediateSupplier<T>)callableOrSupplier).getImmediately(); | ||
|
|
||
| } finally { | ||
| BasicExecutionManager.getPerThreadCurrentTask().set(previousTask); | ||
| perThreadExecutionContext.set(oldExecutionContext); | ||
| } | ||
| } | ||
|
|
||
| @SuppressWarnings({ "unchecked", "rawtypes" }) | ||
| @Override | ||
| protected <T> Task<T> submitInternal(Map<?,?> propertiesQ, final Object task) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I probably agree with this change, but don't feel confident about the full implications of it throwing the exception rather than returning the default value versus absent. In your test
doTestRecursiveConfigFailsGracefullyit certainly makes sense, but not sure what else this will affect.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, the immediate stuff is quite new so i'd prefer to try this. if it's a problem we should perhaps look at wrapping in a
ReferenceWithErroras above, then caller will be forced to deal with the failure in the appropriate way.