Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@andimarek
Copy link
Member

@andimarek andimarek commented Mar 31, 2025

adding a counter to ExecutionContext that tracks if the engine is running

Contains a small breaking change: it makes the ExecutionContext builder non public. I think nobody should create ExecutionContexts outside GraphLQ Java.

@andimarek andimarek requested a review from Copilot March 31, 2025 18:24
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds a counter to the ExecutionContext to track whether the engine is running. The key changes include:

  • Introducing an AtomicInteger (isRunning) with corresponding running() and finished() methods in ExecutionContext.
  • Inserting calls to executionContext.running() and executionContext.finished() across various execution strategy classes.
  • Ensuring that the execution state is tracked consistently during asynchronous execution.

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/main/java/graphql/execution/SubscriptionExecutionStrategy.java Inserts running/finished calls in the subscription strategy; includes an unnecessary semicolon that can be cleaned up.
src/main/java/graphql/execution/ExecutionStrategy.java Adds running/finished calls to track execution state in object and field resolution flows.
src/main/java/graphql/execution/ExecutionContext.java Introduces the AtomicInteger counter and its helper methods for tracking execution state.
src/main/java/graphql/execution/AsyncSerialExecutionStrategy.java Adds running/finished calls around asynchronous field resolution.
src/main/java/graphql/execution/AsyncExecutionStrategy.java Integrates running/finished calls to manage execution state during asynchronous execution.
src/main/java/graphql/execution/AbstractAsyncExecutionStrategy.java Wraps up asynchronous result handling with running/finished calls.

@Override
public CompletableFuture<ExecutionResult> execute(ExecutionContext executionContext, ExecutionStrategyParameters parameters) throws NonNullableFieldWasNullException {

executionContext.running();
Copy link

Copilot AI Mar 31, 2025

Choose a reason for hiding this comment

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

Consider wrapping the code following executionContext.running() in a try-finally block to guarantee that executionContext.finished() is always called, ensuring the counter remains balanced even if exceptions occur.

Copilot uses AI. Check for mistakes.
executionStrategyCtx.onDispatched();

futures.await().whenComplete((completeValueInfos, throwable) -> {
executionContext.running();
Copy link

Copilot AI Mar 31, 2025

Choose a reason for hiding this comment

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

The repeated pattern of invoking executionContext.running() followed by executionContext.finished() could benefit from a refactoring (e.g. using try-finally constructs) to avoid potential imbalances in the counter during asynchronous processing.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

github-actions bot commented Mar 31, 2025

Test Results

  313 files    313 suites   47s ⏱️
3 588 tests 3 582 ✅ 6 💤 0 ❌
3 677 runs  3 671 ✅ 6 💤 0 ❌

Results for commit 339f657.

♻️ This comment has been updated with latest results.

@@ -60,11 +62,13 @@ public CompletableFuture<ExecutionResult> execute(ExecutionContext executionCont
executionStrategyCtx.onDispatched();

futures.await().whenComplete((completeValueInfos, throwable) -> {
Copy link
Member

Choose a reason for hiding this comment

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

Is this missing a executionContext.finished() before the .await() ??

@@ -75,17 +79,21 @@ public CompletableFuture<ExecutionResult> execute(ExecutionContext executionCont
dataLoaderDispatcherStrategy.executionStrategyOnFieldValuesInfo(completeValueInfos);
executionStrategyCtx.onFieldValuesInfo(completeValueInfos);
fieldValuesFutures.await().whenComplete(handleResultsConsumer);
Copy link
Member

Choose a reason for hiding this comment

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

executionContext.finished() before the .await() ??

executionContext.finished();
return CompletableFuture.completedFuture(isNotSensible.get());
}

Copy link
Member

Choose a reason for hiding this comment

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

executionContext.finished() before the Async.eachSequentially ?

Async.CombinedBuilder<Object> resultFutures = fieldValuesCombinedBuilder(completeValueInfos);
dataLoaderDispatcherStrategy.executeObjectOnFieldValuesInfo(completeValueInfos, parameters);
resolveObjectCtx.onFieldValuesInfo(completeValueInfos);
resultFutures.await().whenComplete(handleResultsConsumer);
Copy link
Member

Choose a reason for hiding this comment

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

.await() - should this have a executionContext.finished() before it

Copy link
Member

Choose a reason for hiding this comment

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

imagine this

instead of

executionContext.finished();
resultFutures.await().whenComplete(handleResultsConsumer);

we have helper method in the engine code

awaiting(executionContext, resultFutures.await())

and in that helper method it can

  • call .finished()
  • know when the CF returns and turn itself back on

@@ -69,19 +69,24 @@ public CompletableFuture<ExecutionResult> execute(ExecutionContext executionCont
//
// when the upstream source event stream completes, subscribe to it and wire in our adapter
CompletableFuture<ExecutionResult> overallResult = sourceEventStream.thenApply((publisher) -> {
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to turn this off here ??

executionContext.running();
Object publisher = fetchedValue.getFetchedValue();
if (publisher != null) {
assertTrue(publisher instanceof Publisher, () -> "Your data fetcher must return a Publisher of events when using graphql subscriptions");
Copy link
Member

Choose a reason for hiding this comment

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

If this threw an exception - we would still be running

isRunning.incrementAndGet();
try {
return callable.call();
} catch (Exception e) {
Copy link
Member

Choose a reason for hiding this comment

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

why catch Exception - this seems wrong.

A GraphqlAbort exception for example will be wrapped in RuntimeException and its meaning lost

Ahh Callable throws exception - perhaps make a RuntimeCallable class instead

try {
runnable.run();
;
} catch (Exception e) {
Copy link
Member

Choose a reason for hiding this comment

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

Runnable does not throw exceptions - so dont catch it

@andimarek andimarek added the breaking change requires a new major version to be relased label Apr 2, 2025
}

@Nullable
EngineRunningObserver getEngineRunningObserver() {
Copy link
Member

Choose a reason for hiding this comment

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

@Internal

import static graphql.collect.ImmutableKit.emptyList;

@PublicApi
@Internal
Copy link
Member

Choose a reason for hiding this comment

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

Breaking change

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep ... for 23

@bbakerman bbakerman merged commit 5a03541 into master Apr 2, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change requires a new major version to be relased

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants