Skip to content

Commit 91f1967

Browse files
committed
Removed cancel operation support
1 parent 23012ad commit 91f1967

File tree

5 files changed

+1
-161
lines changed

5 files changed

+1
-161
lines changed

src/main/java/graphql/ExecutionInput.java

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class ExecutionInput {
2929
private final DataLoaderRegistry dataLoaderRegistry;
3030
private final ExecutionId executionId;
3131
private final Locale locale;
32+
// this is currently not used but we want it back soon after the v23 release
3233
private final AtomicBoolean cancelled;
3334

3435

@@ -141,28 +142,6 @@ public Map<String, Object> getExtensions() {
141142
return extensions;
142143
}
143144

144-
145-
/**
146-
* The graphql engine will check this frequently and if that is true, it will
147-
* throw a {@link graphql.execution.AbortExecutionException} to cancel the execution.
148-
* <p>
149-
* This is a cooperative cancellation. Some asynchronous data fetching code may still continue to
150-
* run but there will be no more efforts run future field fetches say.
151-
*
152-
* @return true if the execution should be cancelled
153-
*/
154-
public boolean isCancelled() {
155-
return cancelled.get();
156-
}
157-
158-
/**
159-
* This can be called to cancel the graphql execution. Remember this is a cooperative cancellation
160-
* and the graphql engine needs to be running on a thread to allow is to respect this flag.
161-
*/
162-
public void cancel() {
163-
cancelled.set(true);
164-
}
165-
166145
/**
167146
* This helps you transform the current ExecutionInput object into another one by starting a builder with all
168147
* the current values and allows you to transform it how you want.

src/main/java/graphql/execution/EngineRunningObserver.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package graphql.execution;
22

3-
import graphql.ExecutionInput;
43
import graphql.ExperimentalApi;
54
import graphql.GraphQLContext;
65
import org.jspecify.annotations.NullMarked;
@@ -9,8 +8,6 @@
98
* This class lets you observe the running state of the graphql-java engine. As it processes and dispatches graphql fields,
109
* the engine moves in and out of a running and not running state. As it does this, the callback is called with information telling you the current
1110
* state.
12-
* <p>
13-
* If the engine is cancelled via {@link ExecutionInput#cancel()} then the observer will also be called to indicate that.
1411
*/
1512
@ExperimentalApi
1613
@NullMarked
@@ -25,10 +22,6 @@ enum RunningState {
2522
* Represents that the engine code is asynchronously waiting for fetching to happen
2623
*/
2724
NOT_RUNNING,
28-
/**
29-
* Represents that the engine code has been cancelled via {@link ExecutionInput#cancel()}
30-
*/
31-
CANCELLED
3225
}
3326

3427

src/main/java/graphql/execution/ExecutionContext.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import java.util.function.Supplier;
3838

3939
import static graphql.Assert.assertTrue;
40-
import static graphql.execution.EngineRunningObserver.RunningState.CANCELLED;
4140
import static graphql.execution.EngineRunningObserver.RunningState.NOT_RUNNING;
4241
import static graphql.execution.EngineRunningObserver.RunningState.RUNNING;
4342

@@ -378,15 +377,13 @@ public boolean isRunning() {
378377
}
379378

380379
private void incrementRunning(Throwable throwable) {
381-
checkIsCancelled(throwable);
382380
assertTrue(isRunning.get() >= 0);
383381
if (isRunning.incrementAndGet() == 1) {
384382
changeOfState(RUNNING);
385383
}
386384
}
387385

388386
private void decrementRunning(Throwable throwable) {
389-
checkIsCancelled(throwable);
390387
assertTrue(isRunning.get() > 0);
391388
if (isRunning.decrementAndGet() == 0) {
392389
changeOfState(NOT_RUNNING);
@@ -438,25 +435,6 @@ public void run(Throwable throwable, Runnable runnable) {
438435
}
439436
}
440437

441-
private void checkIsCancelled(Throwable currentThrowable) {
442-
// no need to check we are cancelled if we already have an exception in play
443-
// since it can lead to an exception being thrown when an exception has already been
444-
// thrown
445-
if (currentThrowable == null) {
446-
checkIsCancelled();
447-
}
448-
}
449-
450-
/**
451-
* This will abort the execution via {@link AbortExecutionException} if the {@link ExecutionInput} has been cancelled
452-
*/
453-
private void checkIsCancelled() {
454-
if (executionInput.isCancelled()) {
455-
changeOfState(CANCELLED);
456-
throw new AbortExecutionException("Execution has been asked to be cancelled");
457-
}
458-
}
459-
460438
private void changeOfState(RunningState runningState) {
461439
if (engineRunningObserver != null) {
462440
engineRunningObserver.runningStateChanged(executionId, graphQLContext, runningState);

src/test/groovy/graphql/ExecutionInputTest.groovy

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -167,71 +167,4 @@ class ExecutionInputTest extends Specification {
167167
er.errors.isEmpty()
168168
er.data["fetch"] == "{locale=German, executionId=ID123, graphqlContext=b}"
169169
}
170-
171-
def "can cancel the execution"() {
172-
def sdl = '''
173-
type Query {
174-
fetch1 : Inner
175-
fetch2 : Inner
176-
}
177-
178-
type Inner {
179-
f : String
180-
}
181-
182-
'''
183-
184-
CountDownLatch fieldLatch = new CountDownLatch(1)
185-
186-
DataFetcher df1Sec = { DataFetchingEnvironment env ->
187-
println("Entering DF1")
188-
return CompletableFuture.supplyAsync {
189-
println("DF1 async run")
190-
fieldLatch.await()
191-
Thread.sleep(1000)
192-
return [f: "x"]
193-
}
194-
}
195-
DataFetcher df10Sec = { DataFetchingEnvironment env ->
196-
println("Entering DF10")
197-
return CompletableFuture.supplyAsync {
198-
println("DF10 async run")
199-
fieldLatch.await()
200-
Thread.sleep(10000)
201-
return "x"
202-
}
203-
}
204-
205-
def fetcherMap = ["Query": ["fetch1": df1Sec, "fetch2": df1Sec],
206-
"Inner": ["f": df10Sec]
207-
]
208-
def schema = TestUtil.schema(sdl, fetcherMap)
209-
def graphQL = GraphQL.newGraphQL(schema).build()
210-
211-
when:
212-
ExecutionInput executionInput = ExecutionInput.newExecutionInput()
213-
.query("query q { fetch1 { f } fetch2 { f } }")
214-
.build()
215-
216-
def cf = graphQL.executeAsync(executionInput)
217-
218-
Thread.sleep(250) // let it get into the field fetching say
219-
220-
// lets cancel it
221-
println("cancelling")
222-
executionInput.cancel()
223-
224-
// let the DFs run
225-
println("make the fields run")
226-
fieldLatch.countDown()
227-
228-
println("and await for the overall CF to complete")
229-
Awaitility.await().atMost(Duration.ofSeconds(60)).until({ -> cf.isDone() })
230-
231-
def er = cf.join()
232-
233-
then:
234-
!er.errors.isEmpty()
235-
er.errors[0]["message"] == "Execution has been asked to be cancelled"
236-
}
237170
}

src/test/groovy/graphql/execution/SubscriptionExecutionStrategyTest.groovy

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -710,49 +710,6 @@ class SubscriptionExecutionStrategyTest extends Specification {
710710
}
711711
}
712712
713-
def "we can cancel the operation and the upstream publisher is told"() {
714-
List<Runnable> promises = []
715-
RxJavaMessagePublisher publisher = new RxJavaMessagePublisher(10)
716-
717-
DataFetcher newMessageDF = { env -> return publisher }
718-
DataFetcher senderDF = dfThatDoesNotComplete("sender", promises)
719-
DataFetcher textDF = PropertyDataFetcher.fetching("text")
720-
721-
GraphQL graphQL = buildSubscriptionQL(newMessageDF, senderDF, textDF)
722-
723-
def executionInput = ExecutionInput.newExecutionInput().query("""
724-
subscription NewMessages {
725-
newMessage(roomId: 123) {
726-
sender
727-
text
728-
}
729-
}
730-
""").graphQLContext([(SubscriptionExecutionStrategy.KEEP_SUBSCRIPTION_EVENTS_ORDERED): true]).build()
731-
732-
def executionResult = graphQL.execute(executionInput)
733-
734-
when:
735-
Publisher<ExecutionResult> msgStream = executionResult.getData()
736-
def capturingSubscriber = new CapturingSubscriber<ExecutionResult>(1)
737-
msgStream.subscribe(capturingSubscriber)
738-
739-
// now cancel the operation
740-
executionInput.cancel()
741-
742-
// make things over the subscription
743-
promises.forEach {it.run()}
744-
745-
746-
then:
747-
Awaitility.await().untilTrue(capturingSubscriber.isDone())
748-
749-
def messages = capturingSubscriber.events
750-
messages.size() == 1
751-
def error = messages[0].errors[0]
752-
assert error.message == "Execution has been asked to be cancelled"
753-
publisher.counter == 2
754-
}
755-
756713
private static DataFetcher<?> dfThatDoesNotComplete(String propertyName, List<Runnable> promises) {
757714
{ env ->
758715
def df = PropertyDataFetcher.fetching(propertyName)

0 commit comments

Comments
 (0)