Github user aledsage commented on a diff in the pull request:
https://github.com/apache/brooklyn-server/pull/816#discussion_r141576522
--- Diff:
core/src/main/java/org/apache/brooklyn/util/core/task/BasicExecutionContext.java
---
@@ -100,6 +123,121 @@ public ExecutionManager getExecutionManager() {
@Override
public Set<Task<?>> getTasks() { return
executionManager.getTasksWithAllTags(tags); }
+ @Override
+ public <T> T get(TaskAdaptable<T> task) {
+ final TaskInternal<T> t = (TaskInternal<T>) task.asTask();
+
+ if (t.isQueuedOrSubmitted()) {
+ if (t.isDone()) {
+ return t.getUnchecked();
+ } else {
+ throw new ImmediateUnsupportedException("Task is in
progress and incomplete: "+t);
+ }
+ }
+
+ ContextSwitchingInfo<T> switchContextWrapper =
getContextSwitchingTask(t, Collections.emptyList(), false);
+ if (switchContextWrapper!=null) {
+ return
switchContextWrapper.context.get(switchContextWrapper.wrapperTask);
+ }
+
+ try {
+ return runInSameThread(t, new Callable<Maybe<T>>() {
+ public Maybe<T> call() throws Exception {
+ return Maybe.of(t.getJob().call());
+ }
+ }).get();
+ } catch (Exception e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+
+ private static class SimpleFuture<T> implements Future<T> {
+ boolean cancelled = false;
+ boolean done = false;
+ Maybe<T> result;
+
+ public synchronized Maybe<T> set(Maybe<T> result) {
+ this.result = result;
+ done = true;
+ notifyAll();
+ return result;
+ }
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ cancelled = true;
+ return true;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public boolean isDone() {
+ return done || cancelled;
+ }
+
+ @Override
+ public T get() throws InterruptedException, ExecutionException {
+ if (!isDone()) {
+ synchronized (this) {
+ while (!isDone()) {
+ wait(1000);
+ }
+ }
+ }
+ if (isCancelled() && !done) {
+ throw new CancellationException();
+ }
+ return result.get();
+ }
+
+ @Override
+ public synchronized T get(long timeout, TimeUnit unit) throws
InterruptedException, ExecutionException, TimeoutException {
+ if (isDone()) return get();
+ CountdownTimer time = CountdownTimer.newInstanceStarted(
Duration.of(timeout, unit) );
+ while (!time.isExpired()) {
+
wait(time.getDurationRemaining().lowerBound(Duration.ONE_MILLISECOND).toMilliseconds());
+ if (isDone()) return get();
+ }
+ throw new TimeoutException();
+ }
+ }
+
+ private <T> Maybe<T> runInSameThread(final Task<T> task,
Callable<Maybe<T>> job) throws Exception {
--- End diff --
Thinking about this more, do we really need the two args? For `get()` then
the callable just calls `task.getJob().call()`. For `getImmediately`, I still
don't understand that code but I'd have thought you'd create a
`fakeTaskForContext` that has an appropriate job, rather than
fakeTaskForContext having a null job and passing in the job separately.
---