You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2019/11/05 16:26:58 UTC

[camel] 01/11: CAMEL-14137 Thread leak in camel-jetty component if maxThreads or minThreads property is set

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 27c936a6ff85e54a7cc7a70ce7c15aba762b1fd8
Author: Luigi De Masi <ld...@redhat.com>
AuthorDate: Mon Nov 4 23:30:23 2019 +0100

     CAMEL-14137 Thread leak in camel-jetty component if maxThreads or minThreads property is set
---
 .../camel/component/jetty/JettyHttpComponent.java  | 12 ++++
 .../component/jetty/JettyThreadPoolSizeTest.java   | 72 ++++++++++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
index 22c2c85..cd7645d 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
@@ -134,6 +134,7 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
     protected boolean useXForwardedForHeader;
     private Integer proxyPort;
     private boolean sendServerVersion = true;
+    private QueuedThreadPool _queuedThreadPool;
 
     public JettyHttpComponent() {
     }
@@ -480,6 +481,15 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
                         this.removeServerMBean(connectorRef.server);
                         //mbContainer.removeBean(connectorRef.connector);
                     }
+                    if (_queuedThreadPool !=null){
+                        try {
+                            _queuedThreadPool.stop();
+                        }catch(Throwable t){
+                            _queuedThreadPool.destroy();
+                        }finally {
+                            _queuedThreadPool=null;
+                        }
+                    }
                 }
             }
         }
@@ -1319,6 +1329,8 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
                 qtp.setMaxThreads(maxThreads.intValue());
             }
             tp = qtp;
+            _queuedThreadPool=qtp;
+
         }
         if (tp != null) {
             try {
diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyThreadPoolSizeTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyThreadPoolSizeTest.java
new file mode 100644
index 0000000..27aae78
--- /dev/null
+++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyThreadPoolSizeTest.java
@@ -0,0 +1,72 @@
+package org.apache.camel.component.jetty;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+public class JettyThreadPoolSizeTest extends BaseJettyTest {
+
+
+    private static final Logger log =  LoggerFactory.getLogger(JettyThreadPoolSizeTest.class);
+
+
+    private JettyHttpComponent jettyComponent;
+
+    private RouteBuilder builder;
+
+    @Test
+    public void threadPoolTest(){
+
+
+        Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
+        long initialJettyThreadNumber = threadSet.stream().filter(thread -> thread.getName().contains("CamelJettyServer")).count();
+
+        log.info("initial Jetty thread number (expected 5): "+ initialJettyThreadNumber);
+
+        context.stop();
+
+        Set<Thread> threadSetAfterStop = Thread.getAllStackTraces().keySet();
+        long jettyThreadNumberAfterStop = threadSetAfterStop.stream().filter(thread -> thread.getName().contains("CamelJettyServer")).count();
+
+        log.info("Jetty thread number after stopping Camel Context: (expected 0): "+ jettyThreadNumberAfterStop);
+
+
+        jettyComponent = (JettyHttpComponent)context.getComponent("jetty");
+        jettyComponent.setMinThreads(5);
+        jettyComponent.setMaxThreads(5);
+
+        context.start();
+        Set<Thread> threadSetAfterRestart = Thread.getAllStackTraces().keySet();
+        long jettyThreadNumberAfterRestart = threadSetAfterRestart.stream().filter(thread -> thread.getName().contains("CamelJettyServer")).count();
+
+        log.info("Jetty thread number after starting Camel Context: (expected 5): "+ jettyThreadNumberAfterRestart);
+
+
+        assertEquals(5,initialJettyThreadNumber);
+
+        assertEquals(0,jettyThreadNumberAfterStop);
+
+        assertEquals(5,jettyThreadNumberAfterRestart);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+
+        builder = new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // setup the jetty component with the custom minThreads
+                jettyComponent = (JettyHttpComponent)context.getComponent("jetty");
+                jettyComponent.setMinThreads(5);
+                jettyComponent.setMaxThreads(5);
+
+                from("jetty://http://localhost:{{port}}/myserverWithCustomPoolSize").to("mock:result");
+            }
+        };
+        return builder;
+    }
+
+}