Author: markt
Date: Tue Jun 21 13:45:35 2016
New Revision: 1749509
URL: http://svn.apache.org/viewvc?rev=1749509&view=rev
Log:
Now the WebSocket implementation is not built directly on top of the Servlet
API and can use Tomcat internals, there is no need for the dedicated WebSocket
executor.
Modified:
tomcat/tc8.5.x/trunk/ (props changed)
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/Constants.java
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml
tomcat/tc8.5.x/trunk/webapps/docs/web-socket-howto.xml
Propchange: tomcat/tc8.5.x/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jun 21 13:45:35 2016
@@ -1 +1 @@
-/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737903,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740969,1740980,1740991,1740997,1741015,1741033,1741036,1741058,1741060,1741080,1741147,1741159,1741164,1741173,1741181,1741190,1741197,1741202,1741208,1741213,1741221,1741225,1741232,1741409,1741501
,1741677,1741892,1741896,1741984,1742023,1742042,1742071,1742090,1742093,1742101,1742105,1742111,1742139,1742146,1742148,1742166,1742181,1742184,1742187,1742246,1742248-1742251,1742263-1742264,1742268,1742276,1742369,1742387,1742448,1742509-1742512,1742917,1742919,1742933,1742975-1742976,1742984,1742986,1743019,1743115,1743117,1743124-1743125,1743134,1743425,1743554,1743679,1743696-1743698,1743700-1743701,1744058,1744064-1744065,1744125,1744194,1744229,1744270,1744323,1744432,1744684,1744697,1744705,1744713,1744760,1744786,1745142-1745143,1745145,1745177,1745179-1745180,1745227,1745248,1745254,1745337,1745467,1745576,1745735,1745744,1746304,1746306-1746307,1746319,1746327,1746338,1746340-1746341,1746344,1746427,1746441,1746473,1746490,1746492,1746495-1746496,1746499-1746501,1746503-1746507,1746509,1746549,1746551,1746554,1746556,1746558,1746584,1746620,1746649,1746724,1746939,1746989,1747014,1747028,1747035,1747210,1747225,1747234,1747253,1747404,1747506,1747536,1747924,1747980,1747
993,1748001,1748253,1748452,1748547,1748629,1748676,1748715,1749287,1749296,1749328,1749373,1749465
+/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737903,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740969,1740980,1740991,1740997,1741015,1741033,1741036,1741058,1741060,1741080,1741147,1741159,1741164,1741173,1741181,1741190,1741197,1741202,1741208,1741213,1741221,1741225,1741232,1741409,1741501
,1741677,1741892,1741896,1741984,1742023,1742042,1742071,1742090,1742093,1742101,1742105,1742111,1742139,1742146,1742148,1742166,1742181,1742184,1742187,1742246,1742248-1742251,1742263-1742264,1742268,1742276,1742369,1742387,1742448,1742509-1742512,1742917,1742919,1742933,1742975-1742976,1742984,1742986,1743019,1743115,1743117,1743124-1743125,1743134,1743425,1743554,1743679,1743696-1743698,1743700-1743701,1744058,1744064-1744065,1744125,1744194,1744229,1744270,1744323,1744432,1744684,1744697,1744705,1744713,1744760,1744786,1745142-1745143,1745145,1745177,1745179-1745180,1745227,1745248,1745254,1745337,1745467,1745576,1745735,1745744,1746304,1746306-1746307,1746319,1746327,1746338,1746340-1746341,1746344,1746427,1746441,1746473,1746490,1746492,1746495-1746496,1746499-1746501,1746503-1746507,1746509,1746549,1746551,1746554,1746556,1746558,1746584,1746620,1746649,1746724,1746939,1746989,1747014,1747028,1747035,1747210,1747225,1747234,1747253,1747404,1747506,1747536,1747924,1747980,1747
993,1748001,1748253,1748452,1748547,1748629,1748676,1748715,1749287,1749296,1749328,1749373,1749465,1749506,1749508
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/Constants.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/Constants.java?rev=1749509&r1=1749508&r2=1749509&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/Constants.java
(original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/Constants.java
Tue Jun 21 13:45:35 2016
@@ -28,12 +28,6 @@ public class Constants {
public static final String
ENFORCE_NO_ADD_AFTER_HANDSHAKE_CONTEXT_INIT_PARAM =
"org.apache.tomcat.websocket.noAddAfterHandshake";
- // Executor configuration
- public static final String EXECUTOR_CORE_SIZE_INIT_PARAM =
- "org.apache.tomcat.websocket.executorCoreSize";
- public static final String EXECUTOR_KEEPALIVETIME_SECONDS_INIT_PARAM =
- "org.apache.tomcat.websocket.executorKeepAliveTimeSeconds";
-
public static final String SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE =
"javax.websocket.server.ServerContainer";
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties?rev=1749509&r1=1749508&r2=1749509&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
Tue Jun 21 13:45:35 2016
@@ -22,7 +22,6 @@ serverContainer.missingEndpoint=An Endpo
serverContainer.pojoDeploy=POJO class [{0}] deploying to path [{1}] in
ServletContext [{2}]
serverContainer.servletContextMismatch=Attempted to register a POJO annotated
for WebSocket at path [{0}] in the ServletContext with context path [{1}] when
the WebSocket ServerContainer is allocated to the ServletContext with context
path [{2}]
serverContainer.servletContextMissing=No ServletContext was specified
-serverContainer.threadGroupNotDestroyed=Unable to destroy WebSocket thread
group [{0}] as [{1}] threads were still running when the web application was
stopped. The thread group will be destroyed once the threads terminate.
upgradeUtil.incompatibleRsv=Extensions were specified that have incompatible
RSV bit usage
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java?rev=1749509&r1=1749508&r2=1749509&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
Tue Jun 21 13:45:35 2016
@@ -20,13 +20,13 @@ import java.io.EOFException;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
-import java.util.concurrent.ExecutorService;
-
+import java.util.concurrent.Executor;
import javax.websocket.SendHandler;
import javax.websocket.SendResult;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.net.AbstractEndpoint;
import org.apache.tomcat.util.net.SocketWrapperBase;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tomcat.websocket.Transformation;
@@ -44,7 +44,6 @@ public class WsRemoteEndpointImplServer
private final SocketWrapperBase<?> socketWrapper;
private final WsWriteTimeout wsWriteTimeout;
- private final ExecutorService executorService;
private volatile SendHandler handler = null;
private volatile ByteBuffer[] buffers = null;
@@ -55,7 +54,6 @@ public class WsRemoteEndpointImplServer
WsServerContainer serverContainer) {
this.socketWrapper = socketWrapper;
this.wsWriteTimeout = serverContainer.getTimeout();
- this.executorService = serverContainer.getExecutorService();
}
@@ -227,7 +225,11 @@ public class WsRemoteEndpointImplServer
if (sh != null) {
if (useDispatch) {
OnResultRunnable r = new OnResultRunnable(sh, t);
- if (executorService == null || executorService.isShutdown()) {
+ AbstractEndpoint<?> endpoint = socketWrapper.getEndpoint();
+ Executor containerExecutor = endpoint.getExecutor();
+ if (endpoint.isRunning() && containerExecutor != null) {
+ containerExecutor.execute(r);
+ } else {
// Can't use the executor so call the runnable directly.
// This may not be strictly specification compliant in all
// cases but during shutdown only close messages are going
@@ -236,8 +238,6 @@ public class WsRemoteEndpointImplServer
// 55715. The issues with nested calls was the reason for
// the separate thread requirement in the specification.
r.run();
- } else {
- executorService.execute(r);
}
} else {
if (t == null) {
Modified:
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java?rev=1749509&r1=1749508&r2=1749509&view=diff
==============================================================================
---
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
(original)
+++
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
Tue Jun 21 13:45:35 2016
@@ -27,12 +27,6 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
@@ -50,8 +44,6 @@ import javax.websocket.server.ServerEndp
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.InstanceManager;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tomcat.websocket.WsSession;
@@ -72,7 +64,6 @@ public class WsServerContainer extends W
implements ServerContainer {
private static final StringManager sm =
StringManager.getManager(WsServerContainer.class);
- private static final Log log = LogFactory.getLog(WsServerContainer.class);
private static final CloseReason AUTHENTICATED_HTTP_SESSION_CLOSED =
new CloseReason(CloseCodes.VIOLATED_POLICY,
@@ -91,8 +82,6 @@ public class WsServerContainer extends W
private volatile boolean addAllowed = true;
private final ConcurrentMap<String,Set<WsSession>> authenticatedSessions =
new ConcurrentHashMap<>();
- private final ExecutorService executorService;
- private final ThreadGroup threadGroup;
private volatile boolean endpointsRegistered = false;
WsServerContainer(ServletContext servletContext) {
@@ -118,19 +107,6 @@ public class WsServerContainer extends W
if (value != null) {
setEnforceNoAddAfterHandshake(Boolean.parseBoolean(value));
}
- // Executor config
- int executorCoreSize = 0;
- long executorKeepAliveTimeSeconds = 60;
- value = servletContext.getInitParameter(
- Constants.EXECUTOR_CORE_SIZE_INIT_PARAM);
- if (value != null) {
- executorCoreSize = Integer.parseInt(value);
- }
- value = servletContext.getInitParameter(
- Constants.EXECUTOR_KEEPALIVETIME_SECONDS_INIT_PARAM);
- if (value != null) {
- executorKeepAliveTimeSeconds = Long.parseLong(value);
- }
FilterRegistration.Dynamic fr = servletContext.addFilter(
"Tomcat WebSocket (JSR356) Filter", new WsFilter());
@@ -140,24 +116,6 @@ public class WsServerContainer extends W
DispatcherType.FORWARD);
fr.addMappingForUrlPatterns(types, true, "/*");
-
- // Use a per web application executor for any threads that the
WebSocket
- // server code needs to create. Group all of the threads under a single
- // ThreadGroup.
- StringBuffer threadGroupName = new StringBuffer("WebSocketServer-");
- threadGroupName.append(servletContext.getVirtualServerName());
- threadGroupName.append('-');
- if ("".equals(servletContext.getContextPath())) {
- threadGroupName.append("ROOT");
- } else {
- threadGroupName.append(servletContext.getContextPath());
- }
- threadGroup = new ThreadGroup(threadGroupName.toString());
- WsThreadFactory wsThreadFactory = new WsThreadFactory(threadGroup);
-
- executorService = new ThreadPoolExecutor(executorCoreSize,
- Integer.MAX_VALUE, executorKeepAliveTimeSeconds,
TimeUnit.SECONDS,
- new SynchronousQueue<Runnable>(), wsThreadFactory);
}
@@ -277,50 +235,6 @@ public class WsServerContainer extends W
}
- @Override
- public void destroy() {
- shutdownExecutor();
- super.destroy();
- // If the executor hasn't fully shutdown it won't be possible to
- // destroy this thread group as there will still be threads running.
- // Mark the thread group as daemon one, so that it destroys itself
- // when thread count reaches zero.
- // Synchronization on threadGroup is needed, as there is a race between
- // destroy() call from termination of the last thread in thread group
- // marked as daemon versus the explicit destroy() call.
- int threadCount = threadGroup.activeCount();
- boolean success = false;
- try {
- while (true) {
- int oldThreadCount = threadCount;
- synchronized (threadGroup) {
- if (threadCount > 0) {
- Thread.yield();
- threadCount = threadGroup.activeCount();
- }
- if (threadCount > 0 && threadCount != oldThreadCount) {
- // Value not stabilized. Retry.
- continue;
- }
- if (threadCount > 0) {
- threadGroup.setDaemon(true);
- } else {
- threadGroup.destroy();
- success = true;
- }
- break;
- }
- }
- } catch (IllegalThreadStateException exception) {
- // Fall-through
- }
- if (!success) {
- log.warn(sm.getString("serverContainer.threadGroupNotDestroyed",
- threadGroup.getName(), Integer.valueOf(threadCount)));
- }
- }
-
-
boolean areEndpointsRegistered() {
return endpointsRegistered;
}
@@ -495,23 +409,6 @@ public class WsServerContainer extends W
}
- ExecutorService getExecutorService() {
- return executorService;
- }
-
-
- private void shutdownExecutor() {
- if (executorService == null) {
- return;
- }
- executorService.shutdown();
- try {
- executorService.awaitTermination(10, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- // Ignore the interruption and carry on
- }
- }
-
private static void validateEncoders(Class<? extends Encoder>[] encoders)
throws DeploymentException {
@@ -576,22 +473,4 @@ public class WsServerContainer extends W
tpm2.getUriTemplate().getNormalizedPath());
}
}
-
-
- private static class WsThreadFactory implements ThreadFactory {
-
- private final ThreadGroup tg;
- private final AtomicLong count = new AtomicLong(0);
-
- private WsThreadFactory(ThreadGroup tg) {
- this.tg = tg;
- }
-
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(tg, r);
- t.setName(tg.getName() + "-" + count.incrementAndGet());
- return t;
- }
- }
}
Modified: tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml?rev=1749509&r1=1749508&r2=1749509&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml Tue Jun 21 13:45:35 2016
@@ -94,6 +94,16 @@
</scode>
</changelog>
</subsection>
+ <subsection name="WebSocket">
+ <changelog>
+ <scode>
+ Now the WebSocket implementation is not built directly on top of the
+ Servlet API and can use Tomcat internals, there is no need for the
+ dedicated WebSocket Executor. It has been replaced by the use of the
+ Connector/Endpoint provided Executor. (markt)
+ </scode>
+ </changelog>
+ </subsection>
<subsection name="Tribes">
<changelog>
<add>
Modified: tomcat/tc8.5.x/trunk/webapps/docs/web-socket-howto.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/web-socket-howto.xml?rev=1749509&r1=1749508&r2=1749509&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/webapps/docs/web-socket-howto.xml (original)
+++ tomcat/tc8.5.x/trunk/webapps/docs/web-socket-howto.xml Tue Jun 21 13:45:35
2016
@@ -91,24 +91,6 @@
property to <code>true</code> but any explicit setting on the servlet
context
will always take priority.</p>
-<p>The Java WebSocket 1.0 specification requires that callbacks for
- asynchronous writes are performed on a different thread to the thread that
- initiated the write. Since the container thread pool is not exposed via the
- Servlet API, the WebSocket implementation has to provide its own thread
pool.
- This thread pool is controlled by the following servlet context
- initialization parameters:</p>
- <ul>
- <li><code>org.apache.tomcat.websocket.executorCoreSize</code>: The core
- size of the executor thread pool. If not set, the default of 0 (zero)
- is used. Note that the maximum permitted size of the executor thread
- pool is hard coded to <code>Integer.MAX_VALUE</code> which effectively
- means it is unlimited.</li>
- <li><code>org.apache.tomcat.websocket.executorKeepAliveTimeSeconds</code>:
- The maximum time an idle thread will remain in the executor thread
pool
- until it is terminated. If not specified, the default of 60 seconds is
- used.</li>
- </ul>
-
<p>When using the WebSocket client to connect to server endpoints, the timeout
for IO operations while establishing the connection is controlled by the
<code>userProperties</code> of the provided
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]