diff --git a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AbstractGraphQLHttpServlet.java b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AbstractGraphQLHttpServlet.java index 4a054703..1a955f9e 100644 --- a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AbstractGraphQLHttpServlet.java +++ b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/AbstractGraphQLHttpServlet.java @@ -130,6 +130,7 @@ public String executeQuery(String query) { private void doRequestAsync(HttpServletRequest request, HttpServletResponse response, HttpRequestHandler handler) { if (configuration.isAsyncServletModeEnabled()) { AsyncContext asyncContext = request.startAsync(request, response); + asyncContext.setTimeout(configuration.getAsyncTimeout()); HttpServletRequest asyncRequest = (HttpServletRequest) asyncContext.getRequest(); HttpServletResponse asyncResponse = (HttpServletResponse) asyncContext.getResponse(); configuration.getAsyncExecutor().execute(() -> doRequest(asyncRequest, asyncResponse, handler, asyncContext)); diff --git a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLConfiguration.java b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLConfiguration.java index 8790160b..93a33b23 100644 --- a/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLConfiguration.java +++ b/graphql-java-servlet/src/main/java/graphql/kickstart/servlet/GraphQLConfiguration.java @@ -20,6 +20,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.function.Supplier; +import lombok.Getter; public class GraphQLConfiguration { @@ -32,12 +33,14 @@ public class GraphQLConfiguration { private final boolean asyncServletModeEnabled; private final Executor asyncExecutor; private final long subscriptionTimeout; + @Getter + private final long asyncTimeout; private final ContextSetting contextSetting; private GraphQLConfiguration(GraphQLInvocationInputFactory invocationInputFactory, GraphQLQueryInvoker queryInvoker, GraphQLObjectMapper objectMapper, List<GraphQLServletListener> listeners, boolean asyncServletModeEnabled, - Executor asyncExecutor, long subscriptionTimeout, ContextSetting contextSetting, + Executor asyncExecutor, long subscriptionTimeout, long asyncTimeout, ContextSetting contextSetting, Supplier<BatchInputPreProcessor> batchInputPreProcessor) { this.invocationInputFactory = invocationInputFactory; this.queryInvoker = queryInvoker; @@ -47,6 +50,7 @@ private GraphQLConfiguration(GraphQLInvocationInputFactory invocationInputFactor this.asyncServletModeEnabled = asyncServletModeEnabled; this.asyncExecutor = asyncExecutor; this.subscriptionTimeout = subscriptionTimeout; + this.asyncTimeout = asyncTimeout; this.contextSetting = contextSetting; this.batchInputPreProcessor = batchInputPreProcessor; } @@ -119,8 +123,9 @@ public static class Builder { private boolean asyncServletModeEnabled = false; private Executor asyncExecutor = Executors.newCachedThreadPool(new GraphQLThreadFactory()); private long subscriptionTimeout = 0; + private long asyncTimeout = 30; private ContextSetting contextSetting = ContextSetting.PER_QUERY_WITH_INSTRUMENTATION; - private Supplier<BatchInputPreProcessor> batchInputPreProcessorSupplier = () -> new NoOpBatchInputPreProcessor(); + private Supplier<BatchInputPreProcessor> batchInputPreProcessorSupplier = NoOpBatchInputPreProcessor::new; private Builder(GraphQLInvocationInputFactory.Builder invocationInputFactoryBuilder) { this.invocationInputFactoryBuilder = invocationInputFactoryBuilder; @@ -178,6 +183,11 @@ public Builder with(long subscriptionTimeout) { return this; } + public Builder asyncTimeout(long asyncTimeout) { + this.asyncTimeout = asyncTimeout; + return this; + } + public Builder with(ContextSetting contextSetting) { if (contextSetting != null) { this.contextSetting = contextSetting; @@ -208,6 +218,7 @@ public GraphQLConfiguration build() { asyncServletModeEnabled, asyncExecutor, subscriptionTimeout, + asyncTimeout, contextSetting, batchInputPreProcessorSupplier );