diff options
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/query2/engine/AbstractQueryEnvironment.java | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/query2/engine/AbstractQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/engine/AbstractQueryEnvironment.java index 62fd91b56f..6bc7217b16 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/engine/AbstractQueryEnvironment.java +++ b/src/main/java/com/google/devtools/build/lib/query2/engine/AbstractQueryEnvironment.java @@ -121,8 +121,24 @@ public abstract class AbstractQueryEnvironment<T> implements QueryEnvironment<T> @Override public QueryTaskFuture<Void> eval( - QueryExpression expr, VariableContext<T> context, Callback<T> callback) { - return expr.eval(this, context, callback); + QueryExpression expr, VariableContext<T> context, final Callback<T> callback) { + // Not all QueryEnvironment implementations embrace the async+streaming evaluation framework. In + // particular, the streaming callbacks employed by functions like 'deps' use + // QueryEnvironment#buildTransitiveClosure. So if the implementation of that method does some + // heavyweight blocking work, then it's best to do this blocking work in a single batch. + // Importantly, the callback we pass in needs to maintain order. + final QueryUtil.AggregateAllCallback<T> aggregateAllCallback = + QueryUtil.newOrderedAggregateAllOutputFormatterCallback(); + QueryTaskFuture<Void> evalAllFuture = expr.eval(this, context, aggregateAllCallback); + return whenSucceedsCall( + evalAllFuture, + new QueryTaskCallable<Void>() { + @Override + public Void call() throws QueryException, InterruptedException { + callback.process(aggregateAllCallback.getResult()); + return null; + } + }); } @Override |