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: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to