You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2016/06/21 13:40:32 UTC
svn commit: r1749506 - in /tomcat/trunk:
java/org/apache/tomcat/websocket/server/ webapps/docs/
Author: markt
Date: Tue Jun 21 13:40:32 2016
New Revision: 1749506
URL: http://svn.apache.org/viewvc?rev=1749506&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/trunk/java/org/apache/tomcat/websocket/server/Constants.java
tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
tomcat/trunk/webapps/docs/web-socket-howto.xml
Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/Constants.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/Constants.java?rev=1749506&r1=1749505&r2=1749506&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/Constants.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/Constants.java Tue Jun 21 13:40:32 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/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties?rev=1749506&r1=1749505&r2=1749506&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/LocalStrings.properties Tue Jun 21 13:40:32 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/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java?rev=1749506&r1=1749505&r2=1749506&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsRemoteEndpointImplServer.java Tue Jun 21 13:40:32 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/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java?rev=1749506&r1=1749505&r2=1749506&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java Tue Jun 21 13:40:32 2016
@@ -26,13 +26,6 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
-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;
import javax.servlet.ServletContext;
@@ -49,8 +42,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;
@@ -71,7 +62,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,
@@ -89,8 +79,6 @@ public class WsServerContainer extends W
org.apache.tomcat.websocket.Constants.STRICT_SPEC_COMPLIANCE;
private volatile boolean addAllowed = true;
private final Map<String,Set<WsSession>> authenticatedSessions = new ConcurrentHashMap<>();
- private final ExecutorService executorService;
- private final ThreadGroup threadGroup;
private volatile boolean endpointsRegistered = false;
WsServerContainer(ServletContext servletContext) {
@@ -116,19 +104,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());
@@ -138,24 +113,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);
}
@@ -275,50 +232,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;
}
@@ -493,23 +406,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 {
@@ -574,22 +470,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/trunk/webapps/docs/web-socket-howto.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/web-socket-howto.xml?rev=1749506&r1=1749505&r2=1749506&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/web-socket-howto.xml (original)
+++ tomcat/trunk/webapps/docs/web-socket-howto.xml Tue Jun 21 13:40:32 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: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org