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 2013/12/16 22:05:03 UTC

svn commit: r1551356 - in /tomcat/tc7.0.x/trunk: ./ java/org/apache/tomcat/websocket/server/WsServerContainer.java webapps/docs/changelog.xml

Author: markt
Date: Mon Dec 16 21:05:03 2013
New Revision: 1551356

URL: http://svn.apache.org/r1551356
Log:
Performance improvement
Partial fix for https://issues.apache.org/bugzilla/show_bug.cgi?id=55855
Make the adding of the WsFilter lazy so it doesn't get added to web apps that don't need it.

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1551352

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java?rev=1551356&r1=1551355&r2=1551356&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/websocket/server/WsServerContainer.java Mon Dec 16 21:05:03 2013
@@ -87,74 +87,89 @@ public class WsServerContainer extends W
     private volatile boolean addAllowed = true;
     private final ConcurrentHashMap<String,Set<WsSession>> authenticatedSessions =
             new ConcurrentHashMap<String, Set<WsSession>>();
-    private final ExecutorService executorService;
+    private ExecutorService executorService;
+    private volatile boolean initialized = false;
 
     WsServerContainer(ServletContext servletContext) {
-
         this.servletContext = servletContext;
+    }
 
-        // Configure servlet context wide defaults
-        String value = servletContext.getInitParameter(
-                Constants.BINARY_BUFFER_SIZE_SERVLET_CONTEXT_INIT_PARAM);
-        if (value != null) {
-            setDefaultMaxBinaryMessageBufferSize(Integer.parseInt(value));
-        }
-
-        value = servletContext.getInitParameter(
-                Constants.TEXT_BUFFER_SIZE_SERVLET_CONTEXT_INIT_PARAM);
-        if (value != null) {
-            setDefaultMaxTextMessageBufferSize(Integer.parseInt(value));
-        }
-
-        value = servletContext.getInitParameter(
-                Constants.ENFORCE_NO_ADD_AFTER_HANDSHAKE_CONTEXT_INIT_PARAM);
-        if (value != null) {
-            setEnforceNoAddAfterHandshake(Boolean.parseBoolean(value));
-        }
-        // Executor config
-        int executorCoreSize = 0;
-        int executorMaxSize = 10;
-        long executorKeepAliveTimeSeconds = 60;
-        value = servletContext.getInitParameter(
-                Constants.EXECUTOR_CORE_SIZE_INIT_PARAM);
-        if (value != null) {
-            executorCoreSize = Integer.parseInt(value);
-        }
-        value = servletContext.getInitParameter(
-                Constants.EXECUTOR_MAX_SIZE_INIT_PARAM);
-        if (value != null) {
-            executorMaxSize = Integer.parseInt(value);
-        }
-        value = servletContext.getInitParameter(
-                Constants.EXECUTOR_KEEPALIVETIME_SECONDS_INIT_PARAM);
-        if (value != null) {
-            executorKeepAliveTimeSeconds = Long.parseLong(value);
-        }
-
-        FilterRegistration.Dynamic fr = servletContext.addFilter(
-                WsFilter.class.getName(), new WsFilter());
-        fr.setAsyncSupported(true);
-
-        EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.REQUEST,
-                DispatcherType.FORWARD);
-
-        fr.addMappingForUrlPatterns(types, true, "/*");
-
-        // Use a per web application executor for any threads the the WebSocket
-        // server code needs to create. Group all of the threads under a single
-        // ThreadGroup.
-        StringBuffer threadGroupName = new StringBuffer("WebSocketServer-");
-        if ("".equals(servletContext.getContextPath())) {
-            threadGroupName.append("ROOT");
-        } else {
-            threadGroupName.append(servletContext.getContextPath());
-        }
-        ThreadGroup threadGroup = new ThreadGroup(threadGroupName.toString());
-        WsThreadFactory wsThreadFactory = new WsThreadFactory(threadGroup);
+    private void init() {
+
+        // Double checked locking. This is safe since Java > 1.5 and initialized
+        // is volatile
+        if (initialized) {
+            return;
+        }
+        synchronized (this) {
+            if (initialized) {
+                return;
+            }
+            initialized = true;
+
+            // Configure servlet context wide defaults
+            String value = servletContext.getInitParameter(
+                    Constants.BINARY_BUFFER_SIZE_SERVLET_CONTEXT_INIT_PARAM);
+            if (value != null) {
+                setDefaultMaxBinaryMessageBufferSize(Integer.parseInt(value));
+            }
+
+            value = servletContext.getInitParameter(
+                    Constants.TEXT_BUFFER_SIZE_SERVLET_CONTEXT_INIT_PARAM);
+            if (value != null) {
+                setDefaultMaxTextMessageBufferSize(Integer.parseInt(value));
+            }
 
-        executorService = new ThreadPoolExecutor(executorCoreSize,
-                executorMaxSize, executorKeepAliveTimeSeconds, TimeUnit.SECONDS,
-                new LinkedBlockingQueue<Runnable>(), wsThreadFactory);
+            value = servletContext.getInitParameter(
+                    Constants.ENFORCE_NO_ADD_AFTER_HANDSHAKE_CONTEXT_INIT_PARAM);
+            if (value != null) {
+                setEnforceNoAddAfterHandshake(Boolean.parseBoolean(value));
+            }
+            // Executor config
+            int executorCoreSize = 0;
+            int executorMaxSize = 10;
+            long executorKeepAliveTimeSeconds = 60;
+            value = servletContext.getInitParameter(
+                    Constants.EXECUTOR_CORE_SIZE_INIT_PARAM);
+            if (value != null) {
+                executorCoreSize = Integer.parseInt(value);
+            }
+            value = servletContext.getInitParameter(
+                    Constants.EXECUTOR_MAX_SIZE_INIT_PARAM);
+            if (value != null) {
+                executorMaxSize = 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());
+            fr.setAsyncSupported(true);
+
+            EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.REQUEST,
+                    DispatcherType.FORWARD);
+
+            fr.addMappingForUrlPatterns(types, true, "/*");
+
+            // Use a per web application executor for any threads the the WebSocket
+            // server code needs to create. Group all of the threads under a single
+            // ThreadGroup.
+            StringBuffer threadGroupName = new StringBuffer("WebSocketServer-");
+            if ("".equals(servletContext.getContextPath())) {
+                threadGroupName.append("ROOT");
+            } else {
+                threadGroupName.append(servletContext.getContextPath());
+            }
+            ThreadGroup threadGroup = new ThreadGroup(threadGroupName.toString());
+            WsThreadFactory wsThreadFactory = new WsThreadFactory(threadGroup);
+
+            executorService = new ThreadPoolExecutor(executorCoreSize,
+                    executorMaxSize, executorKeepAliveTimeSeconds, TimeUnit.SECONDS,
+                    new LinkedBlockingQueue<Runnable>(), wsThreadFactory);
+        }
     }
 
 
@@ -170,6 +185,8 @@ public class WsServerContainer extends W
     public void addEndpoint(ServerEndpointConfig sec)
             throws DeploymentException {
 
+        init();
+
         if (enforceNoAddAfterHandshake && !addAllowed) {
             throw new DeploymentException(
                     sm.getString("serverContainer.addNotAllowed"));
@@ -221,6 +238,8 @@ public class WsServerContainer extends W
     @Override
     public void addEndpoint(Class<?> pojo) throws DeploymentException {
 
+        init();
+
         ServerEndpoint annotation = pojo.getAnnotation(ServerEndpoint.class);
         if (annotation == null) {
             throw new DeploymentException(

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1551356&r1=1551355&r2=1551356&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Mon Dec 16 21:05:03 2013
@@ -76,6 +76,11 @@
         Handle the case where a WebSocket annotation configures a message size
         limit larger than the default permitted by Tomcat. (markt)
       </fix>
+      <fix>
+        <bug>55855</bug>: This is a partial fix that makes the additional of the
+        WebSocket Filter lazy so that it is not added to web applications that
+        do not need it. (markt) 
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Cluster">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org