Github user ahgittin commented on a diff in the pull request: https://github.com/apache/brooklyn-server/pull/816#discussion_r141617249 --- 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 -- the two usages of this method have different job-execution semantics. this was the best way to remove the repetition between what those methods did; it was not intended as anything more than that. because the `task` here might be something the caller passed in, i don't think we should try to change the `job`, and so i think we do need both. i'll add javadoc to explain.
---