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

remm pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 7f223b1eb3 Add thread idle time configuration
7f223b1eb3 is described below

commit 7f223b1eb38762fc72a5db35658a00c1aad8186e
Author: remm <r...@apache.org>
AuthorDate: Tue Mar 12 20:38:11 2024 +0100

    Add thread idle time configuration
    
    The default remains 60s.
---
 .../apache/tomcat/util/net/AbstractEndpoint.java   | 29 ++++++++++++++++++++--
 webapps/docs/changelog.xml                         |  6 +++++
 webapps/docs/config/http.xml                       | 13 ++++++++++
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
b/java/org/apache/tomcat/util/net/AbstractEndpoint.java
index bcc2b9ecb9..bfb90b0127 100644
--- a/java/org/apache/tomcat/util/net/AbstractEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AbstractEndpoint.java
@@ -813,6 +813,30 @@ public abstract class AbstractEndpoint<S,U> {
     }
 
 
+    /**
+     * Amount of time in milliseconds before the internal thread pool stops 
any idle threads
+     * if the amount of thread is greater than the minimum amount of spare 
threads.
+     */
+    private int threadsMaxIdleTime = 60000;
+    public void setThreadsMaxIdleTime(int threadsMaxIdleTime) {
+        this.threadsMaxIdleTime = threadsMaxIdleTime;
+        Executor executor = this.executor;
+        if (internalExecutor && executor instanceof ThreadPoolExecutor) {
+            // The internal executor should always be an instance of
+            // org.apache.tomcat.util.threads.ThreadPoolExecutor but it may be
+            // null if the endpoint is not running.
+            // This check also avoids various threading issues.
+            ((ThreadPoolExecutor) 
executor).setKeepAliveTime(threadsMaxIdleTime, TimeUnit.MILLISECONDS);
+        }
+    }
+    public int getThreadsMaxIdleTime() {
+        if (internalExecutor) {
+            return threadsMaxIdleTime;
+        } else {
+            return -1;
+        }
+    }
+
     /**
      * Priority of the worker threads.
      */
@@ -1049,8 +1073,9 @@ public abstract class AbstractEndpoint<S,U> {
         } else {
             TaskQueue taskqueue = new TaskQueue();
             TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", 
daemon, getThreadPriority());
-            executor = new ThreadPoolExecutor(getMinSpareThreads(), 
getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
-            taskqueue.setParent( (ThreadPoolExecutor) executor);
+            executor = new ThreadPoolExecutor(getMinSpareThreads(), 
getMaxThreads(), getThreadsMaxIdleTime(),
+                    TimeUnit.MILLISECONDS, taskqueue, tf);
+            taskqueue.setParent((ThreadPoolExecutor) executor);
         }
     }
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 31fae9bdd2..a5290dd74c 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -171,6 +171,12 @@
         added to the backlog immediately rather than waiting until the write
         attempt for the remaining content. (markt)
       </fix>
+      <fix>
+        Add <code>threadsMaxIdleTime</code> attribute to the endpoint,
+        to allow configuring the amount of time before an internal executor
+        will scale back to the configured <code>minSpareThreads</code> size.
+        (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">
diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
index 2ddefad711..010f40372c 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -707,6 +707,19 @@
       <code>-1</code> to make clear that it is not used.</p>
     </attribute>
 
+    <attribute name="threadsMaxIdleTime" required="false">
+      <p>The amount of time in milliseconds that threads will be kept alive by
+      the thread pool, if there are more than <code>minSpareThreads</code>
+      threads in the executor. If not specified, the default of
+      <code>60000</code> milliseconds is used. If an executor is associated
+      with this connector, this attribute
+      is ignored as the connector will execute tasks using the executor rather
+      than an internal thread pool. Note that if an executor is configured any
+      value set for this attribute will be recorded correctly but it will be
+      reported (e.g. via JMX) as <code>-1</code> to make clear that it is not
+      used.</p>
+    </attribute>
+
     <attribute name="throwOnFailure" required="false">
       <p>If the Connector experiences an Exception during a Lifecycle 
transition
       should the Exception be rethrown or logged? If not specified, the default


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

Reply via email to