-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Added support for async create state in instrumentmentations #3302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| package graphql; | ||
|
|
||
| import graphql.execution.AbortExecutionException; | ||
| import graphql.execution.Async; | ||
| import graphql.execution.AsyncExecutionStrategy; | ||
| import graphql.execution.AsyncSerialExecutionStrategy; | ||
| import graphql.execution.DataFetcherExceptionHandler; | ||
|
|
@@ -421,31 +422,33 @@ public CompletableFuture<ExecutionResult> executeAsync(ExecutionInput executionI | |
| if (logNotSafe.isDebugEnabled()) { | ||
| logNotSafe.debug("Executing request. operation name: '{}'. query: '{}'. variables '{}'", executionInput.getOperationName(), executionInput.getQuery(), executionInput.getVariables()); | ||
| } | ||
| executionInput = ensureInputHasId(executionInput); | ||
| ExecutionInput executionInputWithId = ensureInputHasId(executionInput); | ||
|
|
||
| InstrumentationState instrumentationState = instrumentation.createState(new InstrumentationCreateStateParameters(this.graphQLSchema, executionInput)); | ||
| try { | ||
| InstrumentationExecutionParameters inputInstrumentationParameters = new InstrumentationExecutionParameters(executionInput, this.graphQLSchema, instrumentationState); | ||
| executionInput = instrumentation.instrumentExecutionInput(executionInput, inputInstrumentationParameters, instrumentationState); | ||
|
|
||
| CompletableFuture<ExecutionResult> beginExecutionCF = new CompletableFuture<>(); | ||
| InstrumentationExecutionParameters instrumentationParameters = new InstrumentationExecutionParameters(executionInput, this.graphQLSchema, instrumentationState); | ||
| InstrumentationContext<ExecutionResult> executionInstrumentation = nonNullCtx(instrumentation.beginExecution(instrumentationParameters, instrumentationState)); | ||
| executionInstrumentation.onDispatched(beginExecutionCF); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All this moves into the thenCompose() of state creation |
||
|
|
||
| GraphQLSchema graphQLSchema = instrumentation.instrumentSchema(this.graphQLSchema, instrumentationParameters, instrumentationState); | ||
|
|
||
| CompletableFuture<ExecutionResult> executionResult = parseValidateAndExecute(executionInput, graphQLSchema, instrumentationState); | ||
| // | ||
| // finish up instrumentation | ||
| executionResult = executionResult.whenComplete(completeInstrumentationCtxCF(executionInstrumentation, beginExecutionCF)); | ||
| // | ||
| // allow instrumentation to tweak the result | ||
| executionResult = executionResult.thenCompose(result -> instrumentation.instrumentExecutionResult(result, instrumentationParameters, instrumentationState)); | ||
| return executionResult; | ||
| } catch (AbortExecutionException abortException) { | ||
| return handleAbortException(executionInput, instrumentationState, abortException); | ||
| } | ||
| CompletableFuture<InstrumentationState> instrumentationStateCF = instrumentation.createStateAsync(new InstrumentationCreateStateParameters(this.graphQLSchema, executionInput)); | ||
| return Async.orNullCompletedFuture(instrumentationStateCF).thenCompose(instrumentationState -> { | ||
| try { | ||
| InstrumentationExecutionParameters inputInstrumentationParameters = new InstrumentationExecutionParameters(executionInputWithId, this.graphQLSchema, instrumentationState); | ||
| ExecutionInput instrumentedExecutionInput = instrumentation.instrumentExecutionInput(executionInputWithId, inputInstrumentationParameters, instrumentationState); | ||
|
|
||
| CompletableFuture<ExecutionResult> beginExecutionCF = new CompletableFuture<>(); | ||
| InstrumentationExecutionParameters instrumentationParameters = new InstrumentationExecutionParameters(instrumentedExecutionInput, this.graphQLSchema, instrumentationState); | ||
| InstrumentationContext<ExecutionResult> executionInstrumentation = nonNullCtx(instrumentation.beginExecution(instrumentationParameters, instrumentationState)); | ||
| executionInstrumentation.onDispatched(beginExecutionCF); | ||
|
|
||
| GraphQLSchema graphQLSchema = instrumentation.instrumentSchema(this.graphQLSchema, instrumentationParameters, instrumentationState); | ||
|
|
||
| CompletableFuture<ExecutionResult> executionResult = parseValidateAndExecute(instrumentedExecutionInput, graphQLSchema, instrumentationState); | ||
| // | ||
| // finish up instrumentation | ||
| executionResult = executionResult.whenComplete(completeInstrumentationCtxCF(executionInstrumentation, beginExecutionCF)); | ||
| // | ||
| // allow instrumentation to tweak the result | ||
| executionResult = executionResult.thenCompose(result -> instrumentation.instrumentExecutionResult(result, instrumentationParameters, instrumentationState)); | ||
| return executionResult; | ||
| } catch (AbortExecutionException abortException) { | ||
| return handleAbortException(executionInput, instrumentationState, abortException); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| private CompletableFuture<ExecutionResult> handleAbortException(ExecutionInput executionInput, InstrumentationState instrumentationState, AbortExecutionException abortException) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |
| import graphql.schema.GraphQLSchema; | ||
| import graphql.validation.ValidationError; | ||
| import org.jetbrains.annotations.NotNull; | ||
| import org.jetbrains.annotations.Nullable; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
@@ -80,10 +81,19 @@ private <T> InstrumentationContext<T> chainedCtx(Function<Instrumentation, Instr | |
| return new ChainedInstrumentationContext<>(mapAndDropNulls(instrumentations, mapper)); | ||
| } | ||
|
|
||
| @Override | ||
| public InstrumentationState createState() { | ||
| return Assert.assertShouldNeverHappen("createStateAsync should only ever be used"); | ||
| } | ||
|
|
||
| @Override | ||
| public @Nullable InstrumentationState createState(InstrumentationCreateStateParameters parameters) { | ||
| return Assert.assertShouldNeverHappen("createStateAsync should only ever be used"); | ||
| } | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like it moved but it didnt |
||
|
|
||
| @Override | ||
| public InstrumentationState createState(InstrumentationCreateStateParameters parameters) { | ||
| return new ChainedInstrumentationState(instrumentations, parameters); | ||
| public @NotNull CompletableFuture<InstrumentationState> createStateAsync(InstrumentationCreateStateParameters parameters) { | ||
| return ChainedInstrumentationState.combineAll(instrumentations, parameters); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -349,18 +359,31 @@ public CompletableFuture<ExecutionResult> instrumentExecutionResult(ExecutionRes | |
| } | ||
|
|
||
| static class ChainedInstrumentationState implements InstrumentationState { | ||
| private final Map<Instrumentation, InstrumentationState> instrumentationStates; | ||
| private final Map<Instrumentation, InstrumentationState> instrumentationToStates; | ||
|
|
||
|
|
||
| private ChainedInstrumentationState(List<Instrumentation> instrumentations, InstrumentationCreateStateParameters parameters) { | ||
| instrumentationStates = Maps.newLinkedHashMapWithExpectedSize(instrumentations.size()); | ||
| instrumentations.forEach(i -> instrumentationStates.put(i, i.createState(parameters))); | ||
| private ChainedInstrumentationState(List<Instrumentation> instrumentations, List<InstrumentationState> instrumentationStates) { | ||
| instrumentationToStates = Maps.newLinkedHashMapWithExpectedSize(instrumentations.size()); | ||
| for (int i = 0; i < instrumentations.size(); i++) { | ||
| Instrumentation instrumentation = instrumentations.get(i); | ||
| InstrumentationState instrumentationState = instrumentationStates.get(i); | ||
| instrumentationToStates.put(instrumentation, instrumentationState); | ||
| } | ||
| } | ||
|
|
||
| private InstrumentationState getState(Instrumentation instrumentation) { | ||
| return instrumentationStates.get(instrumentation); | ||
| return instrumentationToStates.get(instrumentation); | ||
| } | ||
|
|
||
| private static CompletableFuture<InstrumentationState> combineAll(List<Instrumentation> instrumentations, InstrumentationCreateStateParameters parameters) { | ||
| Async.CombinedBuilder<InstrumentationState> builder = Async.ofExpectedSize(instrumentations.size()); | ||
| for (Instrumentation instrumentation : instrumentations) { | ||
| // state can be null including the CF so handle that | ||
| CompletableFuture<InstrumentationState> stateCF = Async.orNullCompletedFuture(instrumentation.createStateAsync(parameters)); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we allow null to come back from instrumentation states inline with how it was able to be null before so we have |
||
| builder.add(stateCF); | ||
| } | ||
| return builder.await().thenApply(instrumentationStates -> new ChainedInstrumentationState(instrumentations, instrumentationStates)); | ||
| } | ||
| } | ||
|
|
||
| private static class ChainedInstrumentationContext<T> implements InstrumentationContext<T> { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not effectivly final so we use new variable names