Skip to content

Added ExecutionInput cancellation #3880

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

Merged
merged 10 commits into from
Apr 3, 2025
Merged

Added ExecutionInput cancellation #3880

merged 10 commits into from
Apr 3, 2025

Conversation

bbakerman
Copy link
Member

@bbakerman bbakerman commented Apr 1, 2025

Addressing #3879

This allows the graphql operation to be co-operatively cancelled. It use the "engine run state" tracking to know when its a good time to cancel and abort

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
Copy link
Contributor

github-actions bot commented Apr 1, 2025

Test Results

  313 files  ±0    313 suites  ±0   48s ⏱️ -1s
3 590 tests +2  3 584 ✅ +2  6 💤 ±0  0 ❌ ±0 
3 679 runs  +2  3 673 ✅ +2  6 💤 ±0  0 ❌ ±0 

Results for commit bd4a098. ± Comparison against base commit 5a03541.

This pull request removes 150 and adds 130 tests. Note that renamed tests count towards both.
	?
                __schema { types { fields { args { type { name fields { name }}}}}}
                __schema { types { fields { type { name fields { name }}}}}
                __schema { types { inputFields { type { inputFields { name }}}}}
                __schema { types { interfaces { fields { type { interfaces { name } } } } } }
                __schema { types { name} }
                __type(name : "t") { name }
                a1: __schema { types { name} }
                a1: __type(name : "t") { name }
                a2 :  __type(name : "t1") { name }
…
graphql.ExecutionInputTest ‑ can cancel the execution
graphql.ScalarsBooleanTest ‑ parseValue throws exception for invalid input <java.lang.Object@759cd0b8>
graphql.ScalarsBooleanTest ‑ serialize throws exception for invalid input <java.lang.Object@6bfe5fd3>
graphql.ScalarsIDTest ‑ parseValue allows any object via String.valueOf <java.lang.Object@192de918>
graphql.ScalarsIDTest ‑ serialize allows any object via String.valueOf <java.lang.Object@243b43ed>
graphql.ScalarsIntTest ‑ parseValue throws exception for invalid input <java.lang.Object@615a7c2b>
graphql.ScalarsIntTest ‑ serialize throws exception for invalid input <java.lang.Object@7371b42b>
graphql.execution.SubscriptionExecutionStrategyTest ‑ we can cancel the operation and the upstream publisher is told
graphql.execution.instrumentation.TracingInstrumentationTest ‑ do not trace introspection information [testExecutionStrategy: <graphql.execution.AsyncExecutionStrategy@7c97eb79 fieldCollector=graphql.execution.FieldCollector@55b58dba executionStepInfoFactory=graphql.execution.ExecutionStepInfoFactory@20de1fed dataFetcherExceptionHandler=graphql.execution.SimpleDataFetcherExceptionHandler@3bd2182f resolvedType=graphql.execution.ResolveType@78ddf00f>, #0]
graphql.execution.instrumentation.TracingInstrumentationTest ‑ do not trace introspection information [testExecutionStrategy: <graphql.execution.AsyncSerialExecutionStrategy@510d3c56 fieldCollector=graphql.execution.FieldCollector@7ab55538 executionStepInfoFactory=graphql.execution.ExecutionStepInfoFactory@6dff8fe9 dataFetcherExceptionHandler=graphql.execution.SimpleDataFetcherExceptionHandler@fb6db57 resolvedType=graphql.execution.ResolveType@37e1a97b>, #1]
…

♻️ This comment has been updated with latest results.

@andimarek
Copy link
Member

This should be combined with #3876

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
…ncellation-of-request

# Conflicts:
#	src/main/java/graphql/execution/AsyncExecutionStrategy.java
#	src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java
#	src/main/java/graphql/execution/ExecutionStrategy.java
#	src/main/java/graphql/execution/SubscriptionExecutionStrategy.java
…uest

# Conflicts:
#	src/main/java/graphql/execution/ExecutionContext.java
#	src/main/java/graphql/execution/ExecutionStrategy.java
@@ -306,11 +332,18 @@ public Builder graphQLContext(Map<?, Object> mapOfContext) {
}

// hidden on purpose
private Builder transfer(GraphQLContext graphQLContext) {
private Builder internalTransferContext(GraphQLContext graphQLContext) {
Copy link
Member Author

Choose a reason for hiding this comment

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

I can rename because its private method. This is a transferring of the context to a new instance

@@ -483,7 +483,6 @@ private CompletableFuture<ExecutionResult> parseValidateAndExecute(ExecutionInpu
private PreparsedDocumentEntry parseAndValidate(AtomicReference<ExecutionInput> executionInputRef, GraphQLSchema graphQLSchema, InstrumentationState instrumentationState) {

ExecutionInput executionInput = executionInputRef.get();
String query = executionInput.getQuery();
Copy link
Member Author

Choose a reason for hiding this comment

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

never used. Grey code. took the opportunity to remove it

@@ -22,11 +22,12 @@ public AbstractAsyncExecutionStrategy(DataFetcherExceptionHandler dataFetcherExc
}

protected BiConsumer<List<Object>, Throwable> handleResults(ExecutionContext executionContext, List<String> fieldNames, CompletableFuture<ExecutionResult> overallResult) {
return (List<Object> results, Throwable exception) -> executionContext.run(() -> {
return (List<Object> results, Throwable exception) -> executionContext.run(exception, () -> {
Copy link
Member Author

Choose a reason for hiding this comment

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

whenever we call run here we need to respect if an exception was thrown on the inside when we check if we are cancelled.

There is not point throwing a "cancelled" exception if we are already in exception

* @param executionId the id of the current execution
* @param graphQLContext the graphql context
*/
void runningStateChanged(ExecutionId executionId, GraphQLContext graphQLContext, RunningState runningState);
Copy link
Member Author

Choose a reason for hiding this comment

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

made i an enum versus a boolean

@@ -371,48 +376,89 @@ public boolean isRunning() {
return isRunning.get() > 0;
}

public void incrementRunning() {
if (isRunning.incrementAndGet() == 1 && engineRunningObserver != null) {
engineRunningObserver.runningStateChanged(executionId, graphQLContext, true);
Copy link
Member Author

Choose a reason for hiding this comment

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

never needed to be public. Never used publically

checkIsCancelled(throwable);

if (isRunning.incrementAndGet() == 1) {
changeOfState(RUNNING);
Copy link
Member Author

Choose a reason for hiding this comment

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

changeOfState encapsulates the null check

if (isRunning.incrementAndGet() == 1 && engineRunningObserver != null) {
engineRunningObserver.runningStateChanged(executionId, graphQLContext, true);
private void incrementRunning(Throwable throwable) {
checkIsCancelled(throwable);
Copy link
Member Author

Choose a reason for hiding this comment

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

we now check if we are cancelled in a common place

return executionResult;
});
});
}));
Copy link
Member Author

Choose a reason for hiding this comment

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

looks like formatting

@ExperimentalApi
@NullMarked
public interface EngineRunningObserver {

enum RunningState {
Copy link
Member

Choose a reason for hiding this comment

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

Can we add started and finished here to make it complete?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe not .., we have ways to detect that

@bbakerman bbakerman merged commit aa5afea into master Apr 3, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants