Skip to content

Commit 9eabdde

Browse files
samuelAndalonSamuel Vazquez
and
Samuel Vazquez
authored
feat(batching): v6 check if execution was exhausted when there are errors (#2011)
### 📝 Description #2009 Co-authored-by: Samuel Vazquez <[email protected]>
1 parent a1cdc0f commit 9eabdde

File tree

7 files changed

+113
-43
lines changed

7 files changed

+113
-43
lines changed

executions/graphql-kotlin-dataloader-instrumentation/src/main/kotlin/com/expediagroup/graphql/dataloader/instrumentation/syncexhaustion/DataLoaderSyncExecutionExhaustedInstrumentation.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class DataLoaderSyncExecutionExhaustedInstrumentation : AbstractSyncExecutionExh
4040
parameters: SyncExecutionExhaustedInstrumentationParameters
4141
): OnSyncExecutionExhaustedCallback = { _: List<ExecutionId> ->
4242
parameters
43-
.executionContext.executionInput
43+
.executionInput
4444
.dataLoaderRegistry
4545
.dispatchAll()
4646
}

executions/graphql-kotlin-dataloader-instrumentation/src/main/kotlin/com/expediagroup/graphql/dataloader/instrumentation/syncexhaustion/execution/AbstractSyncExecutionExhaustedInstrumentation.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ abstract class AbstractSyncExecutionExhaustedInstrumentation : SimplePerformantI
5959
): InstrumentationContext<ExecutionResult>? =
6060
parameters.graphQLContext
6161
?.get<SyncExecutionExhaustedState>(SyncExecutionExhaustedState::class)
62-
?.beginExecution(parameters)
62+
?.beginExecution(
63+
parameters,
64+
this.getOnSyncExecutionExhaustedCallback(
65+
SyncExecutionExhaustedInstrumentationParameters(parameters.executionInput)
66+
)
67+
)
6368

6469
override fun beginExecutionStrategy(
6570
parameters: InstrumentationExecutionStrategyParameters,
@@ -78,7 +83,7 @@ abstract class AbstractSyncExecutionExhaustedInstrumentation : SimplePerformantI
7883
?.beginFieldFetch(
7984
parameters,
8085
this.getOnSyncExecutionExhaustedCallback(
81-
SyncExecutionExhaustedInstrumentationParameters(parameters.executionContext)
86+
SyncExecutionExhaustedInstrumentationParameters(parameters.executionContext.executionInput)
8287
)
8388
)
8489
}

executions/graphql-kotlin-dataloader-instrumentation/src/main/kotlin/com/expediagroup/graphql/dataloader/instrumentation/syncexhaustion/execution/SyncExecutionExhaustedInstrumentationParameters.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 Expedia, Inc
2+
* Copyright 2024 Expedia, Inc
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,11 +17,11 @@
1717
package com.expediagroup.graphql.dataloader.instrumentation.syncexhaustion.execution
1818

1919
import com.expediagroup.graphql.dataloader.instrumentation.syncexhaustion.DataLoaderSyncExecutionExhaustedInstrumentation
20-
import graphql.execution.ExecutionContext
20+
import graphql.ExecutionInput
2121

2222
/**
2323
* Hold information that will be provided to an instance of [DataLoaderSyncExecutionExhaustedInstrumentation]
2424
*/
2525
data class SyncExecutionExhaustedInstrumentationParameters(
26-
val executionContext: ExecutionContext
26+
val executionInput: ExecutionInput
2727
)

executions/graphql-kotlin-dataloader-instrumentation/src/main/kotlin/com/expediagroup/graphql/dataloader/instrumentation/syncexhaustion/state/SyncExecutionExhaustedState.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,30 @@ class SyncExecutionExhaustedState(
6767
* @return a non null [InstrumentationContext] object
6868
*/
6969
fun beginExecution(
70-
parameters: InstrumentationExecutionParameters
70+
parameters: InstrumentationExecutionParameters,
71+
onSyncExecutionExhausted: OnSyncExecutionExhaustedCallback
7172
): InstrumentationContext<ExecutionResult> {
7273
executions.computeIfAbsent(parameters.executionInput.executionId) {
7374
ExecutionBatchState()
7475
}
7576
return object : SimpleInstrumentationContext<ExecutionResult>() {
77+
/**
78+
* Remove an [ExecutionBatchState] from the state in case operation does not qualify for starting an execution,
79+
* for example:
80+
* - parsing, validation errors
81+
* - persisted query errors
82+
* - an exception during execution was thrown
83+
*/
7684
override fun onCompleted(result: ExecutionResult?, t: Throwable?) {
7785
if ((result != null && result.errors.size > 0) || t != null) {
78-
removeExecution(parameters.executionInput.executionId)
86+
if (executions.containsKey(parameters.executionInput.executionId)) {
87+
executions.remove(parameters.executionInput.executionId)
88+
totalExecutions.set(totalExecutions.get() - 1)
89+
val allSyncExecutionsExhausted = allSyncExecutionsExhausted()
90+
if (allSyncExecutionsExhausted) {
91+
onSyncExecutionExhausted(executions.keys().toList())
92+
}
93+
}
7994
}
8095
}
8196
}

executions/graphql-kotlin-dataloader-instrumentation/src/test/kotlin/com/expediagroup/graphql/dataloader/instrumentation/fixture/AstronautGraphQL.kt

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 Expedia, Inc
2+
* Copyright 2024 Expedia, Inc
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -197,11 +197,22 @@ object AstronautGraphQL {
197197
)
198198
)
199199

200-
fun execute(
200+
fun executeOperations(
201201
graphQL: GraphQL,
202202
queries: List<String>,
203203
dataLoaderInstrumentationStrategy: DataLoaderInstrumentationStrategy
204-
): Pair<List<ExecutionResult>, KotlinDataLoaderRegistry> {
204+
): Pair<List<Result<ExecutionResult>>, KotlinDataLoaderRegistry> =
205+
execute(
206+
graphQL,
207+
queries.map { query -> ExecutionInput.newExecutionInput(query).build() },
208+
dataLoaderInstrumentationStrategy
209+
)
210+
211+
fun execute(
212+
graphQL: GraphQL,
213+
executionInputs: List<ExecutionInput>,
214+
dataLoaderInstrumentationStrategy: DataLoaderInstrumentationStrategy
215+
): Pair<List<Result<ExecutionResult>>, KotlinDataLoaderRegistry> {
205216
val kotlinDataLoaderRegistry = spyk(
206217
KotlinDataLoaderRegistryFactory(
207218
AstronautDataLoader(),
@@ -214,26 +225,33 @@ object AstronautGraphQL {
214225
when (dataLoaderInstrumentationStrategy) {
215226
DataLoaderInstrumentationStrategy.SYNC_EXHAUSTION ->
216227
SyncExecutionExhaustedState::class to SyncExecutionExhaustedState(
217-
queries.size,
228+
executionInputs.size,
218229
kotlinDataLoaderRegistry
219230
)
220231
DataLoaderInstrumentationStrategy.LEVEL_DISPATCHED ->
221232
ExecutionLevelDispatchedState::class to ExecutionLevelDispatchedState(
222-
queries.size
233+
executionInputs.size
223234
)
224235
}
225236
)
226237

227238
val results = runBlocking {
228-
queries.map { query ->
239+
executionInputs.map { executionInput ->
229240
async {
230-
graphQL.executeAsync(
231-
ExecutionInput
232-
.newExecutionInput(query)
233-
.dataLoaderRegistry(kotlinDataLoaderRegistry)
234-
.graphQLContext(graphQLContext)
235-
.build()
236-
).await()
241+
try {
242+
Result.success(
243+
graphQL.executeAsync(
244+
executionInput.transform { builder ->
245+
builder
246+
.dataLoaderRegistry(kotlinDataLoaderRegistry)
247+
.graphQLContext(graphQLContext)
248+
.build()
249+
}
250+
).await()
251+
)
252+
} catch (e: Exception) {
253+
Result.failure(e)
254+
}
237255
}
238256
}.awaitAll()
239257
}

executions/graphql-kotlin-dataloader-instrumentation/src/test/kotlin/com/expediagroup/graphql/dataloader/instrumentation/level/DataLoaderLevelDispatchedInstrumentationTest.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class DataLoaderLevelDispatchedInstrumentationTest {
4848
"{ mission(id: 4) { designation } }"
4949
)
5050

51-
val (results, kotlinDataLoaderRegistry) = AstronautGraphQL.execute(
51+
val (results, kotlinDataLoaderRegistry) = AstronautGraphQL.executeOperations(
5252
graphQL,
5353
queries,
5454
DataLoaderInstrumentationStrategy.LEVEL_DISPATCHED
@@ -79,7 +79,7 @@ class DataLoaderLevelDispatchedInstrumentationTest {
7979
"{ nasa { mission(id: 4) { id designation } } }"
8080
)
8181

82-
val (results, kotlinDataLoaderRegistry) = AstronautGraphQL.execute(
82+
val (results, kotlinDataLoaderRegistry) = AstronautGraphQL.executeOperations(
8383
graphQL,
8484
queries,
8585
DataLoaderInstrumentationStrategy.LEVEL_DISPATCHED
@@ -114,7 +114,7 @@ class DataLoaderLevelDispatchedInstrumentationTest {
114114
"{ mission(id: 4) { designation } }"
115115
)
116116

117-
val (results, kotlinDataLoaderRegistry) = AstronautGraphQL.execute(
117+
val (results, kotlinDataLoaderRegistry) = AstronautGraphQL.executeOperations(
118118
graphQL,
119119
queries,
120120
DataLoaderInstrumentationStrategy.LEVEL_DISPATCHED
@@ -149,7 +149,7 @@ class DataLoaderLevelDispatchedInstrumentationTest {
149149
"""mutation { createAstronaut(name: "spaceMan") { id name } }"""
150150
)
151151

152-
val (results, _) = AstronautGraphQL.execute(
152+
val (results, _) = AstronautGraphQL.executeOperations(
153153
graphQL,
154154
queries,
155155
DataLoaderInstrumentationStrategy.LEVEL_DISPATCHED
@@ -170,7 +170,7 @@ class DataLoaderLevelDispatchedInstrumentationTest {
170170
"{ mission(id: 4) { designation } }"
171171
)
172172

173-
val (results, kotlinDataLoaderRegistry) = AstronautGraphQL.execute(
173+
val (results, kotlinDataLoaderRegistry) = AstronautGraphQL.executeOperations(
174174
graphQL,
175175
queries,
176176
DataLoaderInstrumentationStrategy.LEVEL_DISPATCHED

0 commit comments

Comments
 (0)