Skip to content

Commit b855d63

Browse files
committed
moved supplier get call into PerRequestBatchedInvocationInput, added some context setting instrumentation tests
1 parent 4e20b75 commit b855d63

File tree

3 files changed

+94
-8
lines changed

3 files changed

+94
-8
lines changed

src/main/java/graphql/servlet/context/ContextSetting.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public GraphQLBatchedInvocationInput getBatch(List<GraphQLRequest> requests, Gra
5454
case PER_REQUEST_WITHOUT_INSTRUMENTATION:
5555
//Intentional fallthrough
5656
case PER_REQUEST_WITH_INSTRUMENTATION:
57-
return new PerRequestBatchedInvocationInput(requests, schema, contextSupplier.get(), root);
57+
return new PerRequestBatchedInvocationInput(requests, schema, contextSupplier, root);
5858
default:
5959
throw new RuntimeException("Unconfigured context setting type");
6060
}
@@ -80,13 +80,12 @@ public Supplier<Instrumentation> configureInstrumentationForContext(Supplier<Ins
8080
(dataLoaderRegistry -> requestTrackingApproach));
8181
break;
8282
case PER_QUERY_WITH_INSTRUMENTATION:
83-
dispatchInstrumentation = new ConfigurableDispatchInstrumentation(options,
84-
(dataLoaderRegistry) -> new FieldLevelTrackingApproach(dataLoaderRegistry));
83+
dispatchInstrumentation = new ConfigurableDispatchInstrumentation(options, FieldLevelTrackingApproach::new);
8584
break;
8685
case PER_REQUEST_WITHOUT_INSTRUMENTATION:
8786
//Intentional fallthrough
8887
case PER_QUERY_WITHOUT_INSTRUMENTATION:
89-
return () -> instrumentation.get();
88+
return instrumentation::get;
9089
default:
9190
throw new RuntimeException("Unconfigured context setting type");
9291
}

src/main/java/graphql/servlet/input/PerRequestBatchedInvocationInput.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import graphql.servlet.core.internal.GraphQLRequest;
66

77
import java.util.List;
8+
import java.util.function.Supplier;
89
import java.util.stream.Collectors;
910

1011
/**
@@ -14,7 +15,8 @@ public class PerRequestBatchedInvocationInput implements GraphQLBatchedInvocatio
1415

1516
private final List<GraphQLSingleInvocationInput> inputs;
1617

17-
public PerRequestBatchedInvocationInput(List<GraphQLRequest> requests, GraphQLSchema schema, GraphQLContext context, Object root) {
18+
public PerRequestBatchedInvocationInput(List<GraphQLRequest> requests, GraphQLSchema schema, Supplier<GraphQLContext> contextSupplier, Object root) {
19+
GraphQLContext context = contextSupplier.get();
1820
inputs = requests.stream().map(request -> new GraphQLSingleInvocationInput(request, schema, context, root)).collect(Collectors.toList());
1921
}
2022

src/test/groovy/graphql/servlet/DataLoaderDispatchingSpec.groovy

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
package graphql.servlet
22

33
import com.fasterxml.jackson.databind.ObjectMapper
4+
import graphql.ExecutionInput
5+
import graphql.execution.instrumentation.ChainedInstrumentation
6+
import graphql.execution.instrumentation.Instrumentation
7+
import graphql.execution.instrumentation.SimpleInstrumentation
8+
import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentationOptions
49
import graphql.schema.DataFetcher
510
import graphql.schema.DataFetchingEnvironment
611
import graphql.servlet.context.DefaultGraphQLContext
712
import graphql.servlet.context.GraphQLContext
813
import graphql.servlet.context.GraphQLContextBuilder
914
import graphql.servlet.context.ContextSetting
15+
import graphql.servlet.instrumentation.ConfigurableDispatchInstrumentation
1016
import org.dataloader.BatchLoader
1117
import org.dataloader.DataLoader
1218
import org.dataloader.DataLoaderRegistry
@@ -111,6 +117,15 @@ class DataLoaderDispatchingSpec extends Specification {
111117
loadCounterB.set(0)
112118
}
113119

120+
List<Map<String, Object>> getBatchedResponseContent() {
121+
mapper.readValue(response.getContentAsByteArray(), List)
122+
}
123+
124+
Instrumentation simpleInstrumentation = new SimpleInstrumentation()
125+
ChainedInstrumentation chainedInstrumentation = new ChainedInstrumentation(Collections.singletonList(simpleInstrumentation))
126+
def simpleSupplier = {simpleInstrumentation}
127+
def chainedSupplier = {chainedInstrumentation}
128+
114129
def "batched query with per query context does not batch loads together"() {
115130
setup:
116131
configureServlet(ContextSetting.PER_QUERY_WITH_INSTRUMENTATION)
@@ -161,7 +176,77 @@ class DataLoaderDispatchingSpec extends Specification {
161176
loadCounterC.get() == 2
162177
}
163178

164-
List<Map<String, Object>> getBatchedResponseContent() {
165-
mapper.readValue(response.getContentAsByteArray(), List)
179+
def unwrapChainedInstrumentations(Instrumentation instrumentation) {
180+
if (!instrumentation instanceof ChainedInstrumentation) {
181+
return Collections.singletonList(instrumentation)
182+
} else {
183+
List<Instrumentation> instrumentations = new ArrayList<>()
184+
for (Instrumentation current : ((ChainedInstrumentation)instrumentation).getInstrumentations()) {
185+
if (current instanceof ChainedInstrumentation) {
186+
instrumentations.addAll(unwrapChainedInstrumentations(current))
187+
} else {
188+
instrumentations.add(current)
189+
}
190+
}
191+
return instrumentations
192+
}
193+
}
194+
195+
def "PER_QUERY_WITHOUT_INSTRUMENTATION does not add instrumentation"() {
196+
when:
197+
def chainedFromContext = ContextSetting.PER_QUERY_WITHOUT_INSTRUMENTATION
198+
.configureInstrumentationForContext(chainedSupplier, Collections.emptyList(), DataLoaderDispatcherInstrumentationOptions.newOptions())
199+
def simpleFromContext = ContextSetting.PER_QUERY_WITHOUT_INSTRUMENTATION
200+
.configureInstrumentationForContext(simpleSupplier, Collections.emptyList(), DataLoaderDispatcherInstrumentationOptions.newOptions())
201+
then:
202+
simpleInstrumentation == simpleFromContext.get()
203+
chainedInstrumentation == chainedFromContext.get()
204+
}
205+
206+
def "PER_REQUEST_WITHOUT_INSTRUMENTATION does not add instrumentation"() {
207+
when:
208+
def chainedFromContext = ContextSetting.PER_REQUEST_WITHOUT_INSTRUMENTATION
209+
.configureInstrumentationForContext(chainedSupplier, Collections.emptyList(), DataLoaderDispatcherInstrumentationOptions.newOptions())
210+
def simpleFromContext = ContextSetting.PER_REQUEST_WITHOUT_INSTRUMENTATION
211+
.configureInstrumentationForContext(simpleSupplier, Collections.emptyList(), DataLoaderDispatcherInstrumentationOptions.newOptions())
212+
then:
213+
simpleInstrumentation == simpleFromContext.get()
214+
chainedInstrumentation == chainedFromContext.get()
215+
}
216+
217+
def "PER_QUERY_WITH_INSTRUMENTATION adds instrumentation"() {
218+
when:
219+
def chainedFromContext = ContextSetting.PER_QUERY_WITH_INSTRUMENTATION
220+
.configureInstrumentationForContext(chainedSupplier, Collections.emptyList(), DataLoaderDispatcherInstrumentationOptions.newOptions())
221+
def simpleFromContext = ContextSetting.PER_QUERY_WITH_INSTRUMENTATION
222+
.configureInstrumentationForContext(simpleSupplier, Collections.emptyList(), DataLoaderDispatcherInstrumentationOptions.newOptions())
223+
def fromSimple = unwrapChainedInstrumentations(simpleFromContext.get())
224+
def fromChained = unwrapChainedInstrumentations(chainedFromContext.get())
225+
then:
226+
fromSimple.size() == 2
227+
fromSimple.contains(simpleInstrumentation)
228+
fromSimple.stream().anyMatch({inst -> inst instanceof ConfigurableDispatchInstrumentation})
229+
fromChained.size() == 2
230+
fromChained.contains(simpleInstrumentation)
231+
fromChained.stream().anyMatch({inst -> inst instanceof ConfigurableDispatchInstrumentation})
232+
}
233+
234+
def "PER_REQUEST_WITH_INSTRUMENTATION adds instrumentation"() {
235+
setup:
236+
ExecutionInput mockInput = ExecutionInput.newExecutionInput().dataLoaderRegistry(new DataLoaderRegistry()).build()
237+
when:
238+
def chainedFromContext = ContextSetting.PER_REQUEST_WITH_INSTRUMENTATION
239+
.configureInstrumentationForContext(chainedSupplier, Collections.singletonList(mockInput), DataLoaderDispatcherInstrumentationOptions.newOptions())
240+
def simpleFromContext = ContextSetting.PER_REQUEST_WITH_INSTRUMENTATION
241+
.configureInstrumentationForContext(simpleSupplier, Collections.singletonList(mockInput), DataLoaderDispatcherInstrumentationOptions.newOptions())
242+
def fromSimple = unwrapChainedInstrumentations(simpleFromContext.get())
243+
def fromChained = unwrapChainedInstrumentations(chainedFromContext.get())
244+
then:
245+
fromSimple.size() == 2
246+
fromSimple.contains(simpleInstrumentation)
247+
fromSimple.stream().anyMatch({inst -> inst instanceof ConfigurableDispatchInstrumentation})
248+
fromChained.size() == 2
249+
fromChained.contains(simpleInstrumentation)
250+
fromChained.stream().anyMatch({inst -> inst instanceof ConfigurableDispatchInstrumentation})
166251
}
167-
}
252+
}

0 commit comments

Comments
 (0)