use of graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext in project graphql-java by graphql-java.
the class SubscriptionExecutionStrategy method execute.
@Override
public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException {
Instrumentation instrumentation = executionContext.getInstrumentation();
InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters);
ExecutionStrategyInstrumentationContext executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters);
CompletableFuture<Publisher<Object>> sourceEventStream = createSourceEventStream(executionContext, parameters);
//
// when the upstream source event stream completes, subscribe to it and wire in our adapter
CompletableFuture<ExecutionResult> overallResult = sourceEventStream.thenApply((publisher) -> {
if (publisher == null) {
return new ExecutionResultImpl(null, executionContext.getErrors());
}
Function<Object, CompletionStage<ExecutionResult>> mapperFunction = eventPayload -> executeSubscriptionEvent(executionContext, parameters, eventPayload);
SubscriptionPublisher mapSourceToResponse = new SubscriptionPublisher(publisher, mapperFunction);
return new ExecutionResultImpl(mapSourceToResponse, executionContext.getErrors());
});
// dispatched the subscription query
executionStrategyCtx.onDispatched(overallResult);
overallResult.whenComplete(executionStrategyCtx::onCompleted);
return overallResult;
}
use of graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext in project graphql-java by graphql-java.
the class FieldLevelTrackingApproach method beginExecutionStrategy.
ExecutionStrategyInstrumentationContext beginExecutionStrategy(InstrumentationExecutionStrategyParameters parameters) {
CallStack callStack = parameters.getInstrumentationState();
ResultPath path = parameters.getExecutionStrategyParameters().getPath();
int parentLevel = path.getLevel();
int curLevel = parentLevel + 1;
int fieldCount = parameters.getExecutionStrategyParameters().getFields().size();
synchronized (callStack) {
callStack.increaseExpectedFetchCount(curLevel, fieldCount);
callStack.increaseHappenedStrategyCalls(curLevel);
}
return new ExecutionStrategyInstrumentationContext() {
@Override
public void onDispatched(CompletableFuture<ExecutionResult> result) {
}
@Override
public void onCompleted(ExecutionResult result, Throwable t) {
}
@Override
public void onFieldValuesInfo(List<FieldValueInfo> fieldValueInfoList) {
boolean dispatchNeeded;
synchronized (callStack) {
dispatchNeeded = handleOnFieldValuesInfo(fieldValueInfoList, callStack, curLevel);
}
if (dispatchNeeded) {
dispatch();
}
}
@Override
public void onFieldValuesException() {
synchronized (callStack) {
callStack.increaseHappenedOnFieldValueCalls(curLevel);
}
}
};
}
use of graphql.execution.instrumentation.ExecutionStrategyInstrumentationContext in project graphql-java by graphql-java.
the class AsyncExecutionStrategy method execute.
@Override
@SuppressWarnings("FutureReturnValueIgnored")
public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException {
Instrumentation instrumentation = executionContext.getInstrumentation();
InstrumentationExecutionStrategyParameters instrumentationParameters = new InstrumentationExecutionStrategyParameters(executionContext, parameters);
ExecutionStrategyInstrumentationContext executionStrategyCtx = instrumentation.beginExecutionStrategy(instrumentationParameters);
MergedSelectionSet fields = parameters.getFields();
Set<String> fieldNames = fields.keySet();
List<CompletableFuture<FieldValueInfo>> futures = new ArrayList<>(fieldNames.size());
List<String> resolvedFields = new ArrayList<>(fieldNames.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));
resolvedFields.add(fieldName);
CompletableFuture<FieldValueInfo> future = resolveFieldWithInfo(executionContext, newParameters);
futures.add(future);
}
CompletableFuture<ExecutionResult> overallResult = new CompletableFuture<>();
executionStrategyCtx.onDispatched(overallResult);
Async.each(futures).whenComplete((completeValueInfos, throwable) -> {
BiConsumer<List<ExecutionResult>, Throwable> handleResultsConsumer = handleResults(executionContext, resolvedFields, overallResult);
if (throwable != null) {
handleResultsConsumer.accept(null, throwable.getCause());
return;
}
List<CompletableFuture<ExecutionResult>> executionResultFuture = map(completeValueInfos, FieldValueInfo::getFieldValue);
executionStrategyCtx.onFieldValuesInfo(completeValueInfos);
Async.each(executionResultFuture).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
// the execution does not hang.
executionStrategyCtx.onFieldValuesException();
overallResult.completeExceptionally(ex);
return null;
});
overallResult.whenComplete(executionStrategyCtx::onCompleted);
return overallResult;
}
Aggregations