Skip to content

Commit 1a6f260

Browse files
committed
Refactor response caching
1 parent 6dad9c6 commit 1a6f260

18 files changed

+263
-240
lines changed

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AbstractGraphQLHttpServlet.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import graphql.kickstart.execution.GraphQLQueryInvoker;
88
import graphql.kickstart.execution.GraphQLRequest;
99
import graphql.kickstart.execution.input.GraphQLSingleInvocationInput;
10-
import graphql.kickstart.servlet.cache.CachingHttpRequestHandlerImpl;
1110
import graphql.kickstart.servlet.core.GraphQLMBean;
1211
import graphql.kickstart.servlet.core.GraphQLServletListener;
1312
import graphql.kickstart.servlet.input.GraphQLInvocationInputFactory;
@@ -65,17 +64,10 @@ public AbstractGraphQLHttpServlet(List<GraphQLServletListener> listeners) {
6564
@Deprecated
6665
protected abstract GraphQLObjectMapper getGraphQLObjectMapper();
6766

68-
/**
69-
* @deprecated override {@link #getConfiguration()} instead
70-
*/
71-
@Deprecated
72-
protected abstract boolean isAsyncServletMode();
73-
7467
protected GraphQLConfiguration getConfiguration() {
7568
return GraphQLConfiguration.with(getInvocationInputFactory())
7669
.with(getQueryInvoker())
7770
.with(getGraphQLObjectMapper())
78-
.with(isAsyncServletMode())
7971
.with(listeners)
8072
.build();
8173
}
@@ -84,11 +76,7 @@ protected GraphQLConfiguration getConfiguration() {
8476
public void init() {
8577
if (configuration == null) {
8678
this.configuration = getConfiguration();
87-
if (configuration.getResponseCacheManager() != null) {
88-
this.requestHandler = new CachingHttpRequestHandlerImpl(configuration);
89-
} else {
90-
this.requestHandler = HttpRequestHandlerFactory.create(configuration);
91-
}
79+
this.requestHandler = configuration.createHttpRequestHandler();
9280
}
9381
}
9482

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/DefaultGraphQLServlet.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,4 @@ protected GraphQLObjectMapper getGraphQLObjectMapper() {
2121
return GraphQLObjectMapper.newBuilder().build();
2222
}
2323

24-
@Override
25-
protected boolean isAsyncServletMode() {
26-
return false;
27-
}
28-
2924
}

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLConfiguration.java

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,19 @@
44
import graphql.kickstart.execution.GraphQLObjectMapper;
55
import graphql.kickstart.execution.GraphQLQueryInvoker;
66
import graphql.kickstart.execution.context.ContextSetting;
7+
import graphql.kickstart.servlet.cache.CachingHttpRequestInvoker;
78
import graphql.kickstart.servlet.cache.GraphQLResponseCacheManager;
89
import graphql.kickstart.servlet.config.DefaultGraphQLSchemaServletProvider;
910
import graphql.kickstart.servlet.config.GraphQLSchemaServletProvider;
1011
import graphql.kickstart.servlet.context.GraphQLServletContextBuilder;
1112
import graphql.kickstart.servlet.core.GraphQLServletListener;
1213
import graphql.kickstart.servlet.core.GraphQLServletRootObjectBuilder;
13-
import graphql.kickstart.servlet.core.internal.GraphQLThreadFactory;
1414
import graphql.kickstart.servlet.input.BatchInputPreProcessor;
1515
import graphql.kickstart.servlet.input.GraphQLInvocationInputFactory;
1616
import graphql.kickstart.servlet.input.NoOpBatchInputPreProcessor;
1717
import graphql.schema.GraphQLSchema;
1818
import java.util.ArrayList;
1919
import java.util.List;
20-
import java.util.concurrent.Executor;
21-
import java.util.concurrent.Executors;
2220
import java.util.function.Supplier;
2321
import lombok.Getter;
2422

@@ -30,19 +28,6 @@ public class GraphQLConfiguration {
3028
private final GraphQLInvoker graphQLInvoker;
3129
private final GraphQLObjectMapper objectMapper;
3230
private final List<GraphQLServletListener> listeners;
33-
/**
34-
* For removal
35-
* @since 10.1.0
36-
*/
37-
@Deprecated
38-
private final boolean asyncServletModeEnabled;
39-
/**
40-
* For removal
41-
* @since 10.1.0
42-
*/
43-
@Deprecated
44-
private final Executor asyncExecutor;
45-
4631
private final long subscriptionTimeout;
4732
@Getter
4833
private final long asyncTimeout;
@@ -52,8 +37,7 @@ public class GraphQLConfiguration {
5237
private GraphQLConfiguration(GraphQLInvocationInputFactory invocationInputFactory,
5338
GraphQLQueryInvoker queryInvoker,
5439
GraphQLObjectMapper objectMapper, List<GraphQLServletListener> listeners,
55-
boolean asyncServletModeEnabled,
56-
Executor asyncExecutor, long subscriptionTimeout, long asyncTimeout,
40+
long subscriptionTimeout, long asyncTimeout,
5741
ContextSetting contextSetting,
5842
Supplier<BatchInputPreProcessor> batchInputPreProcessor,
5943
GraphQLResponseCacheManager responseCacheManager) {
@@ -62,8 +46,6 @@ private GraphQLConfiguration(GraphQLInvocationInputFactory invocationInputFactor
6246
this.graphQLInvoker = queryInvoker.toGraphQLInvoker();
6347
this.objectMapper = objectMapper;
6448
this.listeners = listeners;
65-
this.asyncServletModeEnabled = asyncServletModeEnabled;
66-
this.asyncExecutor = asyncExecutor;
6749
this.subscriptionTimeout = subscriptionTimeout;
6850
this.asyncTimeout = asyncTimeout;
6951
this.contextSetting = contextSetting;
@@ -104,14 +86,6 @@ public List<GraphQLServletListener> getListeners() {
10486
return new ArrayList<>(listeners);
10587
}
10688

107-
public boolean isAsyncServletModeEnabled() {
108-
return asyncServletModeEnabled;
109-
}
110-
111-
public Executor getAsyncExecutor() {
112-
return asyncExecutor;
113-
}
114-
11589
public void add(GraphQLServletListener listener) {
11690
listeners.add(listener);
11791
}
@@ -136,15 +110,21 @@ public GraphQLResponseCacheManager getResponseCacheManager() {
136110
return responseCacheManager;
137111
}
138112

113+
public HttpRequestHandler createHttpRequestHandler() {
114+
HttpRequestHandler requestHandler = HttpRequestHandlerFactory.create(this);
115+
if (responseCacheManager == null) {
116+
return requestHandler;
117+
}
118+
return new HttpRequestHandlerImpl(this, new CachingHttpRequestInvoker(this));
119+
}
120+
139121
public static class Builder {
140122

141123
private GraphQLInvocationInputFactory.Builder invocationInputFactoryBuilder;
142124
private GraphQLInvocationInputFactory invocationInputFactory;
143125
private GraphQLQueryInvoker queryInvoker = GraphQLQueryInvoker.newBuilder().build();
144126
private GraphQLObjectMapper objectMapper = GraphQLObjectMapper.newBuilder().build();
145127
private List<GraphQLServletListener> listeners = new ArrayList<>();
146-
private boolean asyncServletModeEnabled = false;
147-
private Executor asyncExecutor = Executors.newCachedThreadPool(new GraphQLThreadFactory());
148128
private long subscriptionTimeout = 0;
149129
private long asyncTimeout = 30000;
150130
private ContextSetting contextSetting = ContextSetting.PER_QUERY_WITH_INSTRUMENTATION;
@@ -180,18 +160,6 @@ public Builder with(List<GraphQLServletListener> listeners) {
180160
return this;
181161
}
182162

183-
public Builder with(boolean asyncServletModeEnabled) {
184-
this.asyncServletModeEnabled = asyncServletModeEnabled;
185-
return this;
186-
}
187-
188-
public Builder with(Executor asyncExecutor) {
189-
if (asyncExecutor != null) {
190-
this.asyncExecutor = asyncExecutor;
191-
}
192-
return this;
193-
}
194-
195163
public Builder with(GraphQLServletContextBuilder contextBuilder) {
196164
this.invocationInputFactoryBuilder.withGraphQLContextBuilder(contextBuilder);
197165
return this;
@@ -245,8 +213,6 @@ public GraphQLConfiguration build() {
245213
queryInvoker,
246214
objectMapper,
247215
listeners,
248-
asyncServletModeEnabled,
249-
asyncExecutor,
250216
subscriptionTimeout,
251217
asyncTimeout,
252218
contextSetting,

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLHttpServlet.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,4 @@ protected GraphQLObjectMapper getGraphQLObjectMapper() {
3636
throw new UnsupportedOperationException();
3737
}
3838

39-
@Override
40-
protected boolean isAsyncServletMode() {
41-
throw new UnsupportedOperationException();
42-
}
43-
4439
}

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/HttpRequestHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public interface HttpRequestHandler {
1010

1111
int STATUS_OK = 200;
1212
int STATUS_BAD_REQUEST = 400;
13+
int STATUS_INTERNAL_SERVER_ERROR = 500;
1314

1415
void handle(HttpServletRequest request, HttpServletResponse response) throws Exception;
1516

graphql-java-servlet/src/main/java/graphql/kickstart/servlet/HttpRequestHandlerImpl.java

Lines changed: 12 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,27 @@
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
44
import graphql.GraphQLException;
5-
import graphql.kickstart.execution.GraphQLInvoker;
6-
import graphql.kickstart.execution.GraphQLQueryResult;
7-
import graphql.kickstart.execution.input.GraphQLBatchedInvocationInput;
85
import graphql.kickstart.execution.input.GraphQLInvocationInput;
9-
import graphql.kickstart.execution.input.GraphQLSingleInvocationInput;
10-
import graphql.kickstart.servlet.input.BatchInputPreProcessResult;
11-
import graphql.kickstart.servlet.input.BatchInputPreProcessor;
126
import java.io.IOException;
13-
import java.io.UncheckedIOException;
14-
import java.util.concurrent.CompletableFuture;
15-
import javax.servlet.AsyncContext;
167
import javax.servlet.http.HttpServletRequest;
178
import javax.servlet.http.HttpServletResponse;
189
import lombok.extern.slf4j.Slf4j;
1910

2011
@Slf4j
21-
public class HttpRequestHandlerImpl implements HttpRequestHandler {
12+
class HttpRequestHandlerImpl implements HttpRequestHandler {
2213

2314
private final GraphQLConfiguration configuration;
24-
private final GraphQLInvoker graphQLInvoker;
15+
private final HttpRequestInvoker requestInvoker;
2516

2617
public HttpRequestHandlerImpl(GraphQLConfiguration configuration) {
18+
this(configuration, new HttpRequestInvokerImpl(configuration, configuration.getGraphQLInvoker(),
19+
new QueryResponseWriterFactoryImpl()));
20+
}
21+
22+
public HttpRequestHandlerImpl(GraphQLConfiguration configuration,
23+
HttpRequestInvoker requestInvoker) {
2724
this.configuration = configuration;
28-
graphQLInvoker = configuration.getGraphQLInvoker();
25+
this.requestInvoker = requestInvoker;
2926
}
3027

3128
@Override
@@ -39,79 +36,16 @@ public void handle(HttpServletRequest request, HttpServletResponse response) thr
3936
);
4037
GraphQLInvocationInput invocationInput = invocationInputParser
4138
.getGraphQLInvocationInput(request, response);
42-
execute(invocationInput, request, response);
43-
} catch (GraphQLException| JsonProcessingException e) {
39+
requestInvoker.execute(invocationInput, request, response);
40+
} catch (GraphQLException | JsonProcessingException e) {
4441
response.setStatus(STATUS_BAD_REQUEST);
4542
log.info("Bad request: cannot handle http request", e);
4643
throw e;
4744
} catch (Exception t) {
48-
response.setStatus(500);
45+
response.setStatus(STATUS_INTERNAL_SERVER_ERROR);
4946
log.error("Cannot handle http request", t);
5047
throw t;
5148
}
5249
}
5350

54-
protected void execute(GraphQLInvocationInput invocationInput, HttpServletRequest request,
55-
HttpServletResponse response) throws IOException {
56-
if (request.isAsyncSupported()) {
57-
AsyncContext asyncContext = request.isAsyncStarted()
58-
? request.getAsyncContext()
59-
: request.startAsync(request, response);
60-
asyncContext.setTimeout(configuration.getAsyncTimeout());
61-
invoke(invocationInput, request, response)
62-
.thenAccept(result -> writeResultResponse(invocationInput, result, request, response))
63-
.exceptionally(t -> writeErrorResponse(t, response))
64-
.thenAccept(aVoid -> asyncContext.complete());
65-
} else {
66-
try {
67-
GraphQLQueryResult result = invoke(invocationInput, request, response).join();
68-
writeResultResponse(invocationInput, result, request, response);
69-
} catch (Exception t) {
70-
writeErrorResponse(t, response);
71-
}
72-
}
73-
}
74-
75-
private void writeResultResponse(GraphQLInvocationInput invocationInput, GraphQLQueryResult queryResult, HttpServletRequest request,
76-
HttpServletResponse response) {
77-
QueryResponseWriter queryResponseWriter = createWriter(invocationInput, queryResult);
78-
try {
79-
queryResponseWriter.write(request, response);
80-
} catch (IOException e) {
81-
throw new UncheckedIOException(e);
82-
}
83-
}
84-
85-
protected QueryResponseWriter createWriter(GraphQLInvocationInput invocationInput, GraphQLQueryResult queryResult) {
86-
return QueryResponseWriter.createWriter(queryResult, configuration.getObjectMapper(),
87-
configuration.getSubscriptionTimeout());
88-
}
89-
90-
private Void writeErrorResponse(Throwable t, HttpServletResponse response) {
91-
response.setStatus(STATUS_BAD_REQUEST);
92-
log.info("Bad GET request: path was not \"/schema.json\" or no query variable named \"query\" given", t);
93-
return null;
94-
}
95-
96-
private CompletableFuture<GraphQLQueryResult> invoke(GraphQLInvocationInput invocationInput, HttpServletRequest request,
97-
HttpServletResponse response) {
98-
if (invocationInput instanceof GraphQLSingleInvocationInput) {
99-
return graphQLInvoker.queryAsync(invocationInput);
100-
}
101-
return invokeBatched((GraphQLBatchedInvocationInput) invocationInput, request, response);
102-
}
103-
104-
private CompletableFuture<GraphQLQueryResult> invokeBatched(GraphQLBatchedInvocationInput batchedInvocationInput,
105-
HttpServletRequest request,
106-
HttpServletResponse response) {
107-
BatchInputPreProcessor preprocessor = configuration.getBatchInputPreProcessor();
108-
BatchInputPreProcessResult result = preprocessor
109-
.preProcessBatch(batchedInvocationInput, request, response);
110-
if (result.isExecutable()) {
111-
return graphQLInvoker.queryAsync(result.getBatchedInvocationInput());
112-
}
113-
114-
return CompletableFuture.completedFuture(GraphQLQueryResult.createError(result.getStatusCode(), result.getStatusMessage()));
115-
}
116-
11751
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package graphql.kickstart.servlet;
2+
3+
import graphql.kickstart.execution.input.GraphQLInvocationInput;
4+
import javax.servlet.http.HttpServletRequest;
5+
import javax.servlet.http.HttpServletResponse;
6+
7+
public interface HttpRequestInvoker {
8+
9+
void execute(GraphQLInvocationInput invocationInput, HttpServletRequest request,
10+
HttpServletResponse response);
11+
12+
}

0 commit comments

Comments
 (0)