43
43
import graphql .kickstart .execution .config .ObjectMapperProvider ;
44
44
import graphql .kickstart .execution .error .GraphQLErrorHandler ;
45
45
import graphql .kickstart .servlet .AbstractGraphQLHttpServlet ;
46
+ import graphql .kickstart .servlet .AsyncTaskDecorator ;
46
47
import graphql .kickstart .servlet .GraphQLConfiguration ;
47
48
import graphql .kickstart .servlet .GraphQLHttpServlet ;
48
49
import graphql .kickstart .servlet .cache .GraphQLResponseCacheManager ;
61
62
import java .util .List ;
62
63
import java .util .Map ;
63
64
import java .util .Map .Entry ;
65
+ import java .util .concurrent .Executor ;
64
66
import javax .servlet .MultipartConfigElement ;
65
67
import lombok .RequiredArgsConstructor ;
66
68
import lombok .extern .slf4j .Slf4j ;
67
69
import org .springframework .beans .factory .ObjectProvider ;
68
70
import org .springframework .beans .factory .annotation .Autowired ;
71
+ import org .springframework .beans .factory .annotation .Qualifier ;
69
72
import org .springframework .boot .autoconfigure .AutoConfigureAfter ;
70
73
import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
71
74
import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
81
84
import org .springframework .context .annotation .Configuration ;
82
85
import org .springframework .context .annotation .Import ;
83
86
import org .springframework .http .HttpMethod ;
87
+ import org .springframework .scheduling .concurrent .ThreadPoolTaskExecutor ;
84
88
import org .springframework .web .cors .CorsConfiguration ;
85
89
import org .springframework .web .cors .UrlBasedCorsConfigurationSource ;
86
90
import org .springframework .web .filter .CorsFilter ;
101
105
havingValue = "true" ,
102
106
matchIfMissing = true )
103
107
@ AutoConfigureAfter ({GraphQLJavaToolsAutoConfiguration .class , JacksonAutoConfiguration .class })
104
- @ EnableConfigurationProperties ({GraphQLServletProperties .class })
108
+ @ EnableConfigurationProperties ({GraphQLServletProperties .class , AsyncServletProperties . class })
105
109
public class GraphQLWebAutoConfiguration {
106
110
107
111
public static final String QUERY_EXECUTION_STRATEGY = "queryExecutionStrategy" ;
108
112
public static final String MUTATION_EXECUTION_STRATEGY = "mutationExecutionStrategy" ;
109
113
public static final String SUBSCRIPTION_EXECUTION_STRATEGY = "subscriptionExecutionStrategy" ;
110
114
111
115
private final GraphQLServletProperties graphQLServletProperties ;
116
+ private final AsyncServletProperties asyncServletProperties ;
112
117
private final ErrorHandlerSupplier errorHandlerSupplier = new ErrorHandlerSupplier (null );
113
118
114
119
@ Bean
@@ -293,7 +298,13 @@ public GraphQLConfiguration graphQLServletConfiguration(
293
298
GraphQLObjectMapper graphQLObjectMapper ,
294
299
@ Autowired (required = false ) List <GraphQLServletListener > listeners ,
295
300
@ 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 ();
297
308
return GraphQLConfiguration .with (invocationInputFactory )
298
309
.with (graphQLInvoker )
299
310
.with (graphQLObjectMapper )
@@ -302,10 +313,34 @@ public GraphQLConfiguration graphQLServletConfiguration(
302
313
.with (batchInputPreProcessor )
303
314
.with (graphQLServletProperties .getContextSetting ())
304
315
.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 )
306
321
.build ();
307
322
}
308
323
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
+
309
344
@ Bean
310
345
@ ConditionalOnMissingBean
311
346
public GraphQLHttpServlet graphQLHttpServlet (GraphQLConfiguration graphQLConfiguration ) {
@@ -323,7 +358,11 @@ public ServletRegistrationBean<AbstractGraphQLHttpServlet> graphQLServletRegistr
323
358
} else {
324
359
registration .setMultipartConfig (new MultipartConfigElement ("" ));
325
360
}
326
- registration .setAsyncSupported (graphQLServletProperties .isAsyncModeEnabled ());
361
+ if (graphQLServletProperties .getAsyncModeEnabled () != null ) {
362
+ registration .setAsyncSupported (graphQLServletProperties .getAsyncModeEnabled ());
363
+ } else {
364
+ registration .setAsyncSupported (asyncServletProperties .isEnabled ());
365
+ }
327
366
return registration ;
328
367
}
329
368
}
0 commit comments