Skip to content

Commit b56c4f1

Browse files
committed
Polish "Add support for configuring Jetty's backing queue"
See gh-19494
1 parent 852734b commit b56c4f1

File tree

14 files changed

+131
-416
lines changed

14 files changed

+131
-416
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,17 +1032,18 @@ public static class Jetty {
10321032
private Integer selectors = -1;
10331033

10341034
/**
1035-
* Maximum number of threads.
1035+
* Minimum number of threads.
10361036
*/
1037-
private Integer maxThreads = 200;
1037+
private int minThreads = 8;
10381038

10391039
/**
1040-
* Minimum number of threads.
1040+
* Maximum number of threads.
10411041
*/
1042-
private Integer minThreads = 8;
1042+
private int maxThreads = 200;
10431043

10441044
/**
1045-
* Maximum capacity of the thread pools backing queue.
1045+
* Maximum capacity of the thread pool's backing queue. A default is computed
1046+
* based on the threading configuration.
10461047
*/
10471048
private Integer maxQueueCapacity;
10481049

@@ -1095,19 +1096,19 @@ public void setSelectors(Integer selectors) {
10951096
this.selectors = selectors;
10961097
}
10971098

1098-
public void setMinThreads(Integer minThreads) {
1099+
public void setMinThreads(int minThreads) {
10991100
this.minThreads = minThreads;
11001101
}
11011102

1102-
public Integer getMinThreads() {
1103+
public int getMinThreads() {
11031104
return this.minThreads;
11041105
}
11051106

1106-
public void setMaxThreads(Integer maxThreads) {
1107+
public void setMaxThreads(int maxThreads) {
11071108
this.maxThreads = maxThreads;
11081109
}
11091110

1110-
public Integer getMaxThreads() {
1111+
public int getMaxThreads() {
11111112
return this.maxThreads;
11121113
}
11131114

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyConstrainedQueuedThreadPoolFactory.java

Lines changed: 0 additions & 102 deletions
This file was deleted.

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/JettyWebServerFactoryCustomizer.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
import java.time.Duration;
2020
import java.util.Arrays;
21-
import java.util.function.Consumer;
21+
import java.util.concurrent.BlockingQueue;
22+
import java.util.concurrent.SynchronousQueue;
2223

2324
import org.eclipse.jetty.server.AbstractConnector;
2425
import org.eclipse.jetty.server.ConnectionFactory;
@@ -30,6 +31,7 @@
3031
import org.eclipse.jetty.server.handler.ContextHandler;
3132
import org.eclipse.jetty.server.handler.HandlerCollection;
3233
import org.eclipse.jetty.server.handler.HandlerWrapper;
34+
import org.eclipse.jetty.util.BlockingArrayQueue;
3335
import org.eclipse.jetty.util.thread.QueuedThreadPool;
3436
import org.eclipse.jetty.util.thread.ThreadPool;
3537

@@ -75,6 +77,7 @@ public void customize(ConfigurableJettyWebServerFactory factory) {
7577
ServerProperties properties = this.serverProperties;
7678
ServerProperties.Jetty jettyProperties = properties.getJetty();
7779
factory.setUseForwardHeaders(getOrDeduceUseForwardHeaders());
80+
factory.setThreadPool(determineThreadPool(jettyProperties));
7881
PropertyMapper propertyMapper = PropertyMapper.get();
7982
propertyMapper.from(jettyProperties::getAcceptors).whenNonNull().to(factory::setAcceptors);
8083
propertyMapper.from(jettyProperties::getSelectors).whenNonNull().to(factory::setSelectors);
@@ -83,12 +86,6 @@ public void customize(ConfigurableJettyWebServerFactory factory) {
8386
.addServerCustomizers(new MaxHttpHeaderSizeCustomizer(maxHttpHeaderSize)));
8487
propertyMapper.from(jettyProperties::getMaxHttpFormPostSize).asInt(DataSize::toBytes).when(this::isPositive)
8588
.to((maxHttpFormPostSize) -> customizeMaxHttpFormPostSize(factory, maxHttpFormPostSize));
86-
propertyMapper.from(jettyProperties::getMaxThreads).when(this::isPositive)
87-
.to((maxThreads) -> customizeThreadPool(factory, (threadPool) -> threadPool.setMaxThreads(maxThreads)));
88-
propertyMapper.from(jettyProperties::getMinThreads).when(this::isPositive)
89-
.to((minThreads) -> customizeThreadPool(factory, (threadPool) -> threadPool.setMinThreads(minThreads)));
90-
propertyMapper.from(jettyProperties::getThreadIdleTimeout).whenNonNull().asInt(Duration::toMillis).to(
91-
(idleTimeout) -> customizeThreadPool(factory, (threadPool) -> threadPool.setIdleTimeout(idleTimeout)));
9289
propertyMapper.from(properties::getConnectionTimeout).whenNonNull()
9390
.to((connectionTimeout) -> customizeIdleTimeout(factory, connectionTimeout));
9491
propertyMapper.from(jettyProperties::getConnectionIdleTimeout).whenNonNull()
@@ -144,13 +141,25 @@ else if (handler instanceof HandlerCollection) {
144141
});
145142
}
146143

147-
private void customizeThreadPool(ConfigurableJettyWebServerFactory factory, Consumer<QueuedThreadPool> customizer) {
148-
factory.addServerCustomizers((connector) -> {
149-
ThreadPool threadPool = connector.getThreadPool();
150-
if (threadPool instanceof QueuedThreadPool) {
151-
customizer.accept((QueuedThreadPool) threadPool);
152-
}
153-
});
144+
private ThreadPool determineThreadPool(ServerProperties.Jetty properties) {
145+
BlockingQueue<Runnable> queue = determineBlockingQueue(properties.getMaxQueueCapacity());
146+
int maxThreadCount = (properties.getMaxThreads() > 0) ? properties.getMaxThreads() : 200;
147+
int minThreadCount = (properties.getMinThreads() > 0) ? properties.getMinThreads() : 8;
148+
int threadIdleTimeout = (properties.getThreadIdleTimeout() != null)
149+
? (int) properties.getThreadIdleTimeout().toMillis() : 60000;
150+
return new QueuedThreadPool(maxThreadCount, minThreadCount, threadIdleTimeout, queue);
151+
}
152+
153+
private BlockingQueue<Runnable> determineBlockingQueue(Integer maxQueueCapacity) {
154+
if (maxQueueCapacity == null) {
155+
return null;
156+
}
157+
if (maxQueueCapacity == 0) {
158+
return new SynchronousQueue<>();
159+
}
160+
else {
161+
return new BlockingArrayQueue<>(maxQueueCapacity);
162+
}
154163
}
155164

156165
private void customizeAccessLog(ConfigurableJettyWebServerFactory factory,

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@
2424
import org.springframework.beans.factory.ObjectProvider;
2525
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2626
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
27-
import org.springframework.boot.autoconfigure.web.ServerProperties;
28-
import org.springframework.boot.autoconfigure.web.embedded.JettyConstrainedQueuedThreadPoolFactory;
29-
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3027
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
3128
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
32-
import org.springframework.boot.web.embedded.jetty.JettyThreadPoolFactory;
3329
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
3430
import org.springframework.boot.web.embedded.netty.NettyRouteProvider;
3531
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
@@ -105,7 +101,6 @@ TomcatReactiveWebServerFactory tomcatReactiveWebServerFactory(
105101
@Configuration(proxyBeanMethods = false)
106102
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
107103
@ConditionalOnClass({ org.eclipse.jetty.server.Server.class })
108-
@EnableConfigurationProperties(ServerProperties.class)
109104
static class EmbeddedJetty {
110105

111106
@Bean
@@ -114,17 +109,10 @@ JettyResourceFactory jettyServerResourceFactory() {
114109
return new JettyResourceFactory();
115110
}
116111

117-
@Bean
118-
@ConditionalOnMissingBean
119-
JettyThreadPoolFactory jettyThreadPoolFactory(ServerProperties serverProperties) {
120-
return new JettyConstrainedQueuedThreadPoolFactory(serverProperties);
121-
}
122-
123112
@Bean
124113
JettyReactiveWebServerFactory jettyReactiveWebServerFactory(JettyResourceFactory resourceFactory,
125-
JettyThreadPoolFactory threadPoolFactory, ObjectProvider<JettyServerCustomizer> serverCustomizers) {
114+
ObjectProvider<JettyServerCustomizer> serverCustomizers) {
126115
JettyReactiveWebServerFactory serverFactory = new JettyReactiveWebServerFactory();
127-
serverFactory.setThreadPool(threadPoolFactory.create());
128116
serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().collect(Collectors.toList()));
129117
serverFactory.setResourceFactory(resourceFactory);
130118
return serverFactory;

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,8 @@
3232
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3333
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3434
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
35-
import org.springframework.boot.autoconfigure.web.ServerProperties;
36-
import org.springframework.boot.autoconfigure.web.embedded.JettyConstrainedQueuedThreadPoolFactory;
37-
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3835
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
3936
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
40-
import org.springframework.boot.web.embedded.jetty.JettyThreadPoolFactory;
4137
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
4238
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
4339
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
@@ -94,20 +90,12 @@ TomcatServletWebServerFactory tomcatServletWebServerFactory(
9490
@Configuration(proxyBeanMethods = false)
9591
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class })
9692
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
97-
@EnableConfigurationProperties(ServerProperties.class)
9893
static class EmbeddedJetty {
9994

10095
@Bean
101-
@ConditionalOnMissingBean
102-
JettyThreadPoolFactory jettyThreadPoolFactory(ServerProperties serverProperties) {
103-
return new JettyConstrainedQueuedThreadPoolFactory(serverProperties);
104-
}
105-
106-
@Bean
107-
JettyServletWebServerFactory JettyServletWebServerFactory(JettyThreadPoolFactory threadPoolFactory,
96+
JettyServletWebServerFactory JettyServletWebServerFactory(
10897
ObjectProvider<JettyServerCustomizer> serverCustomizers) {
10998
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
110-
factory.setThreadPool(threadPoolFactory.create());
11199
factory.getServerCustomizers().addAll(serverCustomizers.orderedStream().collect(Collectors.toList()));
112100
return factory;
113101
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
* @author Andrew McGhie
7676
* @author HaiTao Zhang
7777
* @author Rafiullah Hamedy
78-
* @author Chris Bono
7978
*/
8079
class ServerPropertiesTests {
8180

0 commit comments

Comments
 (0)