Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,17 @@ public AbstractAsyncExecutionStrategy(DataFetcherExceptionHandler dataFetcherExc
super(dataFetcherExceptionHandler);
}

// This method is kept for backward compatibility. Prefer calling/overriding another handleResults method
protected BiConsumer<List<ExecutionResult>, Throwable> handleResults(ExecutionContext executionContext, List<String> fieldNames, CompletableFuture<ExecutionResult> overallResult) {
return (List<ExecutionResult> results, Throwable exception) -> {
protected BiConsumer<List<Object>, Throwable> handleResults(ExecutionContext executionContext, List<String> fieldNames, CompletableFuture<ExecutionResult> overallResult) {
return (List<Object> results, Throwable exception) -> {
if (exception != null) {
handleNonNullException(executionContext, overallResult, exception);
return;
}
Map<String, Object> resolvedValuesByField = Maps.newLinkedHashMapWithExpectedSize(fieldNames.size());
int ix = 0;
for (ExecutionResult executionResult : results) {
for (Object result : results) {
String fieldName = fieldNames.get(ix++);
resolvedValuesByField.put(fieldName, executionResult.getData());
resolvedValuesByField.put(fieldName, result);
}
overallResult.complete(new ExecutionResultImpl(resolvedValuesByField, executionContext.getErrors()));
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above is a breaking change IF we consider the ExecutionStrategy API - which I argue we should re-consider

};
Expand Down
23 changes: 6 additions & 17 deletions src/main/java/graphql/execution/AsyncExecutionStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,35 +42,24 @@ public CompletableFuture<ExecutionResult> execute(ExecutionContext executionCont

ExecutionStrategyInstrumentationContext executionStrategyCtx = ExecutionStrategyInstrumentationContext.nonNullCtx(instrumentation.beginExecutionStrategy(instrumentationParameters, executionContext.getInstrumentationState()));

MergedSelectionSet fields = parameters.getFields();
List<String> fieldNames = fields.getKeys();
Async.CombinedBuilder<FieldValueInfo> futures = Async.ofExpectedSize(fields.size());
for (String fieldName : fieldNames) {
MergedField currentField = fields.getSubField(fieldName);

ResultPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField));
ExecutionStrategyParameters newParameters = parameters
.transform(builder -> builder.field(currentField).path(fieldPath).parent(parameters));

CompletableFuture<FieldValueInfo> future = resolveFieldWithInfo(executionContext, newParameters);
futures.add(future);
}
List<String> fieldNames = parameters.getFields().getKeys();
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the above is moved into the getAsyncFieldValueInfo method since its commonly used

Async.CombinedBuilder<FieldValueInfo> futures = getAsyncFieldValueInfo(executionContext, parameters);
CompletableFuture<ExecutionResult> overallResult = new CompletableFuture<>();
executionStrategyCtx.onDispatched(overallResult);

futures.await().whenComplete((completeValueInfos, throwable) -> {
BiConsumer<List<ExecutionResult>, Throwable> handleResultsConsumer = handleResults(executionContext, fieldNames, overallResult);
BiConsumer<List<Object>, Throwable> handleResultsConsumer = handleResults(executionContext, fieldNames, overallResult);
if (throwable != null) {
handleResultsConsumer.accept(null, throwable.getCause());
return;
}

Async.CombinedBuilder<ExecutionResult> executionResultFutures = Async.ofExpectedSize(completeValueInfos.size());
Async.CombinedBuilder<Object> fieldValuesFutures = Async.ofExpectedSize(completeValueInfos.size());
for (FieldValueInfo completeValueInfo : completeValueInfos) {
executionResultFutures.add(completeValueInfo.getFieldValue());
fieldValuesFutures.add(completeValueInfo.getFieldValueFuture());
}
executionStrategyCtx.onFieldValuesInfo(completeValueInfos);
executionResultFutures.await().whenComplete(handleResultsConsumer);
fieldValuesFutures.await().whenComplete(handleResultsConsumer);
}).exceptionally((ex) -> {
// if there are any issues with combining/handling the field results,
// complete the future at all costs and bubble up any thrown exception so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public CompletableFuture<ExecutionResult> execute(ExecutionContext executionCont
MergedSelectionSet fields = parameters.getFields();
ImmutableList<String> fieldNames = ImmutableList.copyOf(fields.keySet());

CompletableFuture<List<ExecutionResult>> resultsFuture = Async.eachSequentially(fieldNames, (fieldName, prevResults) -> {
CompletableFuture<List<Object>> resultsFuture = Async.eachSequentially(fieldNames, (fieldName, prevResults) -> {
MergedField currentField = fields.getSubField(fieldName);
ResultPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField));
ExecutionStrategyParameters newParameters = parameters
Expand Down
Loading