4343import graphql .kickstart .execution .config .ObjectMapperProvider ;
4444import graphql .kickstart .execution .error .GraphQLErrorHandler ;
4545import graphql .kickstart .servlet .AbstractGraphQLHttpServlet ;
46+ import graphql .kickstart .servlet .AsyncTaskDecorator ;
4647import graphql .kickstart .servlet .GraphQLConfiguration ;
4748import graphql .kickstart .servlet .GraphQLHttpServlet ;
4849import graphql .kickstart .servlet .cache .GraphQLResponseCacheManager ;
6162import java .util .List ;
6263import java .util .Map ;
6364import java .util .Map .Entry ;
65+ import java .util .concurrent .Executor ;
6466import javax .servlet .MultipartConfigElement ;
6567import lombok .RequiredArgsConstructor ;
6668import lombok .extern .slf4j .Slf4j ;
6769import org .springframework .beans .factory .ObjectProvider ;
6870import org .springframework .beans .factory .annotation .Autowired ;
71+ import org .springframework .beans .factory .annotation .Qualifier ;
6972import org .springframework .boot .autoconfigure .AutoConfigureAfter ;
7073import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
7174import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
8184import org .springframework .context .annotation .Configuration ;
8285import org .springframework .context .annotation .Import ;
8386import org .springframework .http .HttpMethod ;
87+ import org .springframework .scheduling .concurrent .ThreadPoolTaskExecutor ;
8488import org .springframework .web .cors .CorsConfiguration ;
8589import org .springframework .web .cors .UrlBasedCorsConfigurationSource ;
8690import org .springframework .web .filter .CorsFilter ;
101105 havingValue = "true" ,
102106 matchIfMissing = true )
103107@ AutoConfigureAfter ({GraphQLJavaToolsAutoConfiguration .class , JacksonAutoConfiguration .class })
104- @ EnableConfigurationProperties ({GraphQLServletProperties .class })
108+ @ EnableConfigurationProperties ({GraphQLServletProperties .class , AsyncServletProperties . class })
105109public class GraphQLWebAutoConfiguration {
106110
107111 public static final String QUERY_EXECUTION_STRATEGY = "queryExecutionStrategy" ;
108112 public static final String MUTATION_EXECUTION_STRATEGY = "mutationExecutionStrategy" ;
109113 public static final String SUBSCRIPTION_EXECUTION_STRATEGY = "subscriptionExecutionStrategy" ;
110114
111115 private final GraphQLServletProperties graphQLServletProperties ;
116+ private final AsyncServletProperties asyncServletProperties ;
112117 private final ErrorHandlerSupplier errorHandlerSupplier = new ErrorHandlerSupplier (null );
113118
114119 @ Bean
@@ -293,7 +298,13 @@ public GraphQLConfiguration graphQLServletConfiguration(
293298 GraphQLObjectMapper graphQLObjectMapper ,
294299 @ Autowired (required = false ) List <GraphQLServletListener > listeners ,
295300 @ Autowired (required = false ) BatchInputPreProcessor batchInputPreProcessor ,
296- @ Autowired (required = false ) GraphQLResponseCacheManager responseCacheManager ) {
301+ @ Autowired (required = false ) GraphQLResponseCacheManager responseCacheManager ,
302+ @ Autowired (required = false ) AsyncTaskDecorator asyncTaskDecorator ,
303+ @ Autowired (required = false ) @ Qualifier ("graphqlAsyncTaskExecutor" ) Executor asyncExecutor ) {
304+ long asyncTimeout =
305+ graphQLServletProperties .getAsyncTimeout () != null
306+ ? graphQLServletProperties .getAsyncTimeout ()
307+ : asyncServletProperties .getTimeout ();
297308 return GraphQLConfiguration .with (invocationInputFactory )
298309 .with (graphQLInvoker )
299310 .with (graphQLObjectMapper )
@@ -302,10 +313,34 @@ public GraphQLConfiguration graphQLServletConfiguration(
302313 .with (batchInputPreProcessor )
303314 .with (graphQLServletProperties .getContextSetting ())
304315 .with (responseCacheManager )
305- .asyncTimeout (graphQLServletProperties .getAsyncTimeout ())
316+ .asyncTimeout (asyncTimeout )
317+ .with (asyncTaskDecorator )
318+ .asyncCorePoolSize (asyncServletProperties .getThreads ().getMin ())
319+ .asyncCorePoolSize (asyncServletProperties .getThreads ().getMax ())
320+ .with (asyncExecutor )
306321 .build ();
307322 }
308323
324+ @ Bean ("graphqlAsyncTaskExecutor" )
325+ @ ConditionalOnMissingBean (name = "graphqlAsyncTaskExecutor" )
326+ public Executor threadPoolTaskExecutor () {
327+ if (isAsyncModeEnabled ()) {
328+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor ();
329+ executor .setCorePoolSize (asyncServletProperties .getThreads ().getMin ());
330+ executor .setMaxPoolSize (asyncServletProperties .getThreads ().getMax ());
331+ executor .setThreadNamePrefix (asyncServletProperties .getThreads ().getNamePrefix ());
332+ executor .initialize ();
333+ return executor ;
334+ }
335+ return null ;
336+ }
337+
338+ private boolean isAsyncModeEnabled () {
339+ return graphQLServletProperties .getAsyncModeEnabled () != null
340+ ? graphQLServletProperties .getAsyncModeEnabled ()
341+ : asyncServletProperties .isEnabled ();
342+ }
343+
309344 @ Bean
310345 @ ConditionalOnMissingBean
311346 public GraphQLHttpServlet graphQLHttpServlet (GraphQLConfiguration graphQLConfiguration ) {
@@ -323,7 +358,11 @@ public ServletRegistrationBean<AbstractGraphQLHttpServlet> graphQLServletRegistr
323358 } else {
324359 registration .setMultipartConfig (new MultipartConfigElement ("" ));
325360 }
326- registration .setAsyncSupported (graphQLServletProperties .isAsyncModeEnabled ());
361+ if (graphQLServletProperties .getAsyncModeEnabled () != null ) {
362+ registration .setAsyncSupported (graphQLServletProperties .getAsyncModeEnabled ());
363+ } else {
364+ registration .setAsyncSupported (asyncServletProperties .isEnabled ());
365+ }
327366 return registration ;
328367 }
329368}
0 commit comments