public Execution(ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, Instrumentation instrumentation) { this.queryStrategy = queryStrategy != null ? queryStrategy : new AsyncExecutionStrategy(); this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new AsyncSerialExecutionStrategy(); this.subscriptionStrategy = subscriptionStrategy != null ? subscriptionStrategy : new AsyncExecutionStrategy(); this.instrumentation = instrumentation; }
@Override public CompletableFuture<ExecutionResult> execute(final ExecutionContext executionContext, final ExecutionStrategyParameters parameters) { if (executorService == null) { return new AsyncExecutionStrategy().execute(executionContext, parameters);
@SuppressWarnings("FutureReturnValueIgnored") private Supplier<CompletableFuture<ExecutionResult>> deferredExecutionResult(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { return () -> { GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField()); GraphQLObjectType fieldContainer = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); Instrumentation instrumentation = executionContext.getInstrumentation(); DeferredFieldInstrumentationContext fieldCtx = instrumentation.beginDeferredField( new InstrumentationDeferredFieldParameters(executionContext, parameters, fieldDef, createExecutionStepInfo(executionContext, parameters, fieldDef, fieldContainer)) ); CompletableFuture<ExecutionResult> result = new CompletableFuture<>(); fieldCtx.onDispatched(result); CompletableFuture<FieldValueInfo> fieldValueInfoFuture = resolveFieldWithInfo(executionContext, parameters); fieldValueInfoFuture.whenComplete((fieldValueInfo, throwable) -> { fieldCtx.onFieldValueInfo(fieldValueInfo); CompletableFuture<ExecutionResult> execResultFuture = fieldValueInfo.getFieldValue(); execResultFuture = execResultFuture.whenComplete(fieldCtx::onCompleted); Async.copyResults(execResultFuture, result); }); return result; }; } }
MergedField currentField = fields.getSubField(fieldName); ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField)); ExecutionStrategyParameters newParameters = parameters .transform(builder -> builder.field(currentField).path(fieldPath).parent(parameters)); if (isDeferred(executionContext, newParameters, currentField)) { executionStrategyCtx.onDeferredField(currentField); continue; CompletableFuture<FieldValueInfo> future = resolveFieldWithInfo(executionContext, newParameters); futures.add(future); BiConsumer<List<ExecutionResult>, Throwable> handleResultsConsumer = handleResults(executionContext, resolvedFields, overallResult); if (throwable != null) { handleResultsConsumer.accept(null, throwable.getCause());
GraphQLObjectType parentType = parameters.typeInfo().castType(GraphQLObjectType.class); return super.execute(executionContext, parameters).thenApply(sourceResult -> { Map<String, Object> data = sourceResult.getData(); if (parameters.source() instanceof TypedValue) {
private boolean isDeferred(ExecutionContext executionContext, ExecutionStrategyParameters parameters, MergedField currentField) { DeferSupport deferSupport = executionContext.getDeferSupport(); if (deferSupport.checkForDeferDirective(currentField)) { DeferredErrorSupport errorSupport = new DeferredErrorSupport(); // with a deferred field we are really resetting where we execute from, that is from this current field onwards Map<String, MergedField> fields = new LinkedHashMap<>(); fields.put(currentField.getName(), currentField); ExecutionStrategyParameters callParameters = parameters.transform(builder -> { MergedSelectionSet mergedSelectionSet = newMergedSelectionSet().subFields(fields).build(); builder.deferredErrorSupport(errorSupport) .field(currentField) .fields(mergedSelectionSet) .parent(null) // this is a break in the parent -> child chain - its a new start effectively .listSize(0) .currentListIndex(0); } ); DeferredCall call = new DeferredCall(deferredExecutionResult(executionContext, callParameters), errorSupport); deferSupport.enqueue(call); return true; } return false; }
MergedField currentField = fields.getSubField(fieldName); ExecutionPath fieldPath = parameters.getPath().segment(mkNameForPath(currentField)); ExecutionStrategyParameters newParameters = parameters .transform(builder -> builder.field(currentField).path(fieldPath).parent(parameters)); if (isDeferred(executionContext, newParameters, currentField)) { executionStrategyCtx.onDeferredField(currentField); continue; CompletableFuture<FieldValueInfo> future = resolveFieldWithInfo(executionContext, newParameters); futures.add(future); BiConsumer<List<ExecutionResult>, Throwable> handleResultsConsumer = handleResults(executionContext, resolvedFields, overallResult); if (throwable != null) { handleResultsConsumer.accept(null, throwable.getCause());
private boolean isDeferred(ExecutionContext executionContext, ExecutionStrategyParameters parameters, MergedField currentField) { DeferSupport deferSupport = executionContext.getDeferSupport(); if (deferSupport.checkForDeferDirective(currentField)) { DeferredErrorSupport errorSupport = new DeferredErrorSupport(); // with a deferred field we are really resetting where we execute from, that is from this current field onwards Map<String, MergedField> fields = new LinkedHashMap<>(); fields.put(currentField.getName(), currentField); ExecutionStrategyParameters callParameters = parameters.transform(builder -> { MergedSelectionSet mergedSelectionSet = newMergedSelectionSet().subFields(fields).build(); builder.deferredErrorSupport(errorSupport) .field(currentField) .fields(mergedSelectionSet) .parent(null) // this is a break in the parent -> child chain - its a new start effectively .listSize(0) .currentListIndex(0); } ); DeferredCall call = new DeferredCall(deferredExecutionResult(executionContext, callParameters), errorSupport); deferSupport.enqueue(call); return true; } return false; }
private void exceptionHandler() { //::FigureI DataFetcherExceptionHandler handler = new DataFetcherExceptionHandler() { @Override public DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandlerParameters handlerParameters) { // // do your custom handling here. The parameters have all you need GraphQLError buildCustomError = buildCustomError(handlerParameters); return DataFetcherExceptionHandlerResult.newResult() .error(buildCustomError).build(); } }; ExecutionStrategy executionStrategy = new AsyncExecutionStrategy(handler); //::/FigureI }
@Override public CompletableFuture<ExecutionResult> execute(final ExecutionContext executionContext, final ExecutionStrategyParameters parameters) { if (executorService == null) { return new AsyncExecutionStrategy().execute(executionContext, parameters);
@SuppressWarnings("FutureReturnValueIgnored") private Supplier<CompletableFuture<ExecutionResult>> deferredExecutionResult(ExecutionContext executionContext, ExecutionStrategyParameters parameters) { return () -> { GraphQLFieldDefinition fieldDef = getFieldDef(executionContext, parameters, parameters.getField().getSingleField()); GraphQLObjectType fieldContainer = (GraphQLObjectType) parameters.getExecutionStepInfo().getUnwrappedNonNullType(); Instrumentation instrumentation = executionContext.getInstrumentation(); DeferredFieldInstrumentationContext fieldCtx = instrumentation.beginDeferredField( new InstrumentationDeferredFieldParameters(executionContext, parameters, fieldDef, createExecutionStepInfo(executionContext, parameters, fieldDef, fieldContainer)) ); CompletableFuture<ExecutionResult> result = new CompletableFuture<>(); fieldCtx.onDispatched(result); CompletableFuture<FieldValueInfo> fieldValueInfoFuture = resolveFieldWithInfo(executionContext, parameters); fieldValueInfoFuture.whenComplete((fieldValueInfo, throwable) -> { fieldCtx.onFieldValueInfo(fieldValueInfo); CompletableFuture<ExecutionResult> execResultFuture = fieldValueInfo.getFieldValue(); execResultFuture = execResultFuture.whenComplete(fieldCtx::onCompleted); Async.copyResults(execResultFuture, result); }); return result; }; } }
void executionStrategies() { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, /* core pool size 2 thread */ 2, /* max pool size 2 thread */ 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy()); GraphQL graphQL = GraphQL.newGraphQL(StarWarsSchema.starWarsSchema) .queryExecutionStrategy(new ExecutorServiceExecutionStrategy(threadPoolExecutor)) .mutationExecutionStrategy(new AsyncExecutionStrategy()) .subscriptionExecutionStrategy(new AsyncExecutionStrategy()) .build(); }
private GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, ExecutionIdProvider idProvider, Instrumentation instrumentation, PreparsedDocumentProvider preparsedDocumentProvider) { this.graphQLSchema = assertNotNull(graphQLSchema, "graphQLSchema must be non null"); this.queryStrategy = queryStrategy != null ? queryStrategy : new AsyncExecutionStrategy(); this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new AsyncSerialExecutionStrategy(); this.subscriptionStrategy = subscriptionStrategy != null ? subscriptionStrategy : new SubscriptionExecutionStrategy(); this.idProvider = assertNotNull(idProvider, "idProvider must be non null"); this.instrumentation = checkInstrumentation(assertNotNull(instrumentation)); this.preparsedDocumentProvider = assertNotNull(preparsedDocumentProvider, "preparsedDocumentProvider must be non null"); }
private void wireInExecutionStrategies() { //::FigureG GraphQL.newGraphQL(schema) .queryExecutionStrategy(new AsyncExecutionStrategy()) .mutationExecutionStrategy(new AsyncSerialExecutionStrategy()) .build(); //::/FigureG }
public Execution(ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, Instrumentation instrumentation) { this.queryStrategy = queryStrategy != null ? queryStrategy : new AsyncExecutionStrategy(); this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new AsyncSerialExecutionStrategy(); this.subscriptionStrategy = subscriptionStrategy != null ? subscriptionStrategy : new AsyncExecutionStrategy(); this.instrumentation = instrumentation; }
@Bean @ConditionalOnMissingBean public ExecutionStrategyProvider executionStrategyProvider() { if (executionStrategies == null || executionStrategies.isEmpty()) { return new DefaultExecutionStrategyProvider(new AsyncExecutionStrategy(), null, new SubscriptionExecutionStrategy()); } else if (executionStrategies.entrySet().size() == 1) { return new DefaultExecutionStrategyProvider(executionStrategies.entrySet().stream().findFirst().get().getValue()); } else { if (!executionStrategies.containsKey(QUERY_EXECUTION_STRATEGY)) { throwIncorrectExecutionStrategyNameException(); } if (executionStrategies.size() == 2 && !(executionStrategies.containsKey(MUTATION_EXECUTION_STRATEGY) || executionStrategies.containsKey(SUBSCRIPTION_EXECUTION_STRATEGY))) { throwIncorrectExecutionStrategyNameException(); } if (executionStrategies.size() >= 3 && !(executionStrategies.containsKey(MUTATION_EXECUTION_STRATEGY) && executionStrategies.containsKey(SUBSCRIPTION_EXECUTION_STRATEGY))) { throwIncorrectExecutionStrategyNameException(); } return new DefaultExecutionStrategyProvider( executionStrategies.get(QUERY_EXECUTION_STRATEGY), executionStrategies.get(MUTATION_EXECUTION_STRATEGY), executionStrategies.get(SUBSCRIPTION_EXECUTION_STRATEGY) ); } }
public DefaultExecutionStrategyProvider(ExecutionStrategy queryExecutionStrategy, ExecutionStrategy mutationExecutionStrategy, ExecutionStrategy subscriptionExecutionStrategy) { this.queryExecutionStrategy = defaultIfNull(queryExecutionStrategy, new AsyncExecutionStrategy()); this.mutationExecutionStrategy = defaultIfNull(mutationExecutionStrategy, this.queryExecutionStrategy); this.subscriptionExecutionStrategy = defaultIfNull(subscriptionExecutionStrategy, new SubscriptionExecutionStrategy()); }
private GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy, ExecutionStrategy subscriptionStrategy, ExecutionIdProvider idProvider, Instrumentation instrumentation, PreparsedDocumentProvider preparsedDocumentProvider) { this.graphQLSchema = assertNotNull(graphQLSchema, "graphQLSchema must be non null"); this.queryStrategy = queryStrategy != null ? queryStrategy : new AsyncExecutionStrategy(); this.mutationStrategy = mutationStrategy != null ? mutationStrategy : new AsyncSerialExecutionStrategy(); this.subscriptionStrategy = subscriptionStrategy != null ? subscriptionStrategy : new SubscriptionExecutionStrategy(); this.idProvider = assertNotNull(idProvider, "idProvider must be non null"); this.instrumentation = checkInstrumentation(assertNotNull(instrumentation)); this.preparsedDocumentProvider = assertNotNull(preparsedDocumentProvider, "preparsedDocumentProvider must be non null"); }