Update thread pool settings in STOMP/WebSocket config

The clientInboundChannel and clientOutboundChannel now use twice
the number of available processors by default to accomodate for some
degree of blocking in task execution on average.

In practice these settings still need to be configured explicitly in
applications but these should serve as better default values than
the default values in ThreadPoolTaskExecutor.

Issue: SPR-11450
This commit is contained in:
Rossen Stoyanchev
2014-03-20 00:41:31 -04:00
parent 9cee70ff66
commit 10af128e96
7 changed files with 175 additions and 89 deletions

View File

@@ -201,6 +201,9 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
}
else if (!channelName.equals("brokerChannel")) {
executorDef = new RootBeanDefinition(ThreadPoolTaskExecutor.class);
executorDef.getPropertyValues().add("corePoolSize", Runtime.getRuntime().availableProcessors() * 2);
executorDef.getPropertyValues().add("maxPoolSize", Integer.MAX_VALUE);
executorDef.getPropertyValues().add("queueCapacity", Integer.MAX_VALUE);
}
ConstructorArgumentValues values = new ConstructorArgumentValues();

View File

@@ -152,7 +152,7 @@
<xsd:annotation>
<xsd:documentation source="java:org.springframework.web.socket.sockjs.support.AbstractSockJsService"><![CDATA[
Minimum number of bytes that can be send over a single HTTP streaming request before it will be closed.
Defaults to 128K (i.e. 128 * 1024).
Defaults to 128K (i.e. 128 1024).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -346,31 +346,44 @@
<xsd:attribute name="core-pool-size" type="xsd:int" use="optional">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><![CDATA[
The core pool size. Default value is 1.
Set the core pool size of the ThreadPoolExecutor.
NOTE: the core pool size is effectively the max pool size when an unbounded queue-capacity is configured (the default).
This is essentially the "Unbounded queues" strategy as explained in java.util.concurrent.ThreadPoolExecutor.
When this strategy is used, the max pool size is effectively ignored.
By default this is set to twice the value of Runtime.availableProcessors().
In an an application where tasks do not block frequently,
the number should be closer to or equal to the number of available CPUs/cores.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-pool-size" type="xsd:int" use="optional">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><![CDATA[
The maximum pool size. Default value is Integer.MAX_VALUE.
Set the max pool size of the ThreadPoolExecutor.
NOTE: when an unbounded queue-capacity is configured (the default), the max pool size is effectively ignored.
See the "Unbounded queues" strategy in java.util.concurrent.ThreadPoolExecutor for more details.
By default this is set to Integer.MAX_VALUE.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="keep-alive-seconds" type="xsd:int" use="optional">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><![CDATA[
The keep-alive value in seconds. Default value 60.
Set the time limit for which threads may remain idle before being terminated.
If there are more than the core number of threads currently in the pool, after waiting this amount of time without
processing a task, excess threads will be terminated. This overrides any value set in the constructor.
By default this is set to 60.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="queue-capacity" type="xsd:int" use="optional">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><![CDATA[
The capacity for the executor's BlockingQueue.
Default is Integer.MAX_VALUE.
Any positive value will lead to a LinkedBlockingQueue instance;
any other value will lead to a SynchronousQueue instance.
Set the queue capacity for the ThreadPoolExecutor.
NOTE: when an unbounded queue-capacity is configured (the default) the core pool size is effectively the max pool size.
This is essentially the "Unbounded queues" strategy as explained in java.util.concurrent.ThreadPoolExecutor.
When this strategy is used, the max pool size is effectively ignored.
By default this is set to Integer.MAX_VALUE.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>

View File

@@ -136,11 +136,11 @@ public class MessageBrokerBeanDefinitionParserTests {
Arrays.<Class<? extends MessageHandler>>asList(SimpAnnotationMethodMessageHandler.class,
UserDestinationMessageHandler.class, SimpleBrokerMessageHandler.class);
testChannel("clientInboundChannel", subscriberTypes, 0);
testExecutor("clientInboundChannel", 1, Integer.MAX_VALUE, 60);
testExecutor("clientInboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60);
subscriberTypes = Arrays.<Class<? extends MessageHandler>>asList(SubProtocolWebSocketHandler.class);
testChannel("clientOutboundChannel", subscriberTypes, 0);
testExecutor("clientOutboundChannel", 1, Integer.MAX_VALUE, 60);
testExecutor("clientOutboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60);
subscriberTypes = Arrays.<Class<? extends MessageHandler>>asList(
SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class);
@@ -199,11 +199,11 @@ public class MessageBrokerBeanDefinitionParserTests {
Arrays.<Class<? extends MessageHandler>>asList(SimpAnnotationMethodMessageHandler.class,
UserDestinationMessageHandler.class, StompBrokerRelayMessageHandler.class);
testChannel("clientInboundChannel", subscriberTypes, 0);
testExecutor("clientInboundChannel", 1, Integer.MAX_VALUE, 60);
testExecutor("clientInboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60);
subscriberTypes = Arrays.<Class<? extends MessageHandler>>asList(SubProtocolWebSocketHandler.class);
testChannel("clientOutboundChannel", subscriberTypes, 0);
testExecutor("clientOutboundChannel", 1, Integer.MAX_VALUE, 60);
testExecutor("clientOutboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60);
subscriberTypes = Arrays.<Class<? extends MessageHandler>>asList(
StompBrokerRelayMessageHandler.class, UserDestinationMessageHandler.class);