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 2023/05/22 12:40:55 UTC

[tomcat] 02/02: Add useVirtualThreads attribute to endpoints.

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

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

commit e5decc41fbf1be8285db1924b6f8384078225cdd
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri May 12 17:30:27 2023 +0100

    Add useVirtualThreads attribute to endpoints.
    
    Refactor VirtualThreadExecutor so it can be used by the Endpoint
---
 .../apache/catalina/core/LocalStrings.properties   |  5 +--
 ...tor.java => StandardVirtualThreadExecutor.java} | 23 +++++++------
 .../apache/tomcat/util/net/AbstractEndpoint.java   | 23 ++++++++++---
 .../tomcat/util/threads/VirtualThreadExecutor.java | 40 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  4 +--
 webapps/docs/config/ajp.xml                        |  7 ++++
 webapps/docs/config/executor.xml                   |  4 +--
 webapps/docs/config/http.xml                       |  7 ++++
 8 files changed, 93 insertions(+), 20 deletions(-)

diff --git a/java/org/apache/catalina/core/LocalStrings.properties b/java/org/apache/catalina/core/LocalStrings.properties
index 64fc860dac..47959993dd 100644
--- a/java/org/apache/catalina/core/LocalStrings.properties
+++ b/java/org/apache/catalina/core/LocalStrings.properties
@@ -286,6 +286,9 @@ standardService.stop.name=Stopping service [{0}]
 
 standardThreadExecutor.notStarted=The executor has not been started
 
+standardVirtualThreadExecutor.notStarted=The executor has not been started
+standardVirtualThreadExecutor.noVirtualThreads=Virtual threads require a minimum Java version of Java 21
+
 standardWrapper.allocate=Error allocating a servlet instance
 standardWrapper.allocateException=Allocate exception for servlet [{0}]
 standardWrapper.deallocateException=Deallocate exception for servlet [{0}]
@@ -309,5 +312,3 @@ standardWrapper.waiting=Waiting for [{0}] instance(s) to be deallocated for Serv
 
 threadLocalLeakPreventionListener.containerEvent.error=Exception processing container event [{0}]
 threadLocalLeakPreventionListener.lifecycleEvent.error=Exception processing lifecycle event [{0}]
-
-virtualThreadExecutor.noVirtualThreads=Virtual threads require a minimum Java version of Java 21
\ No newline at end of file
diff --git a/java/org/apache/catalina/core/VirtualThreadExecutor.java b/java/org/apache/catalina/core/StandardVirtualThreadExecutor.java
similarity index 79%
rename from java/org/apache/catalina/core/VirtualThreadExecutor.java
rename to java/org/apache/catalina/core/StandardVirtualThreadExecutor.java
index 496aeb3303..d9d584ee41 100644
--- a/java/org/apache/catalina/core/VirtualThreadExecutor.java
+++ b/java/org/apache/catalina/core/StandardVirtualThreadExecutor.java
@@ -24,18 +24,17 @@ import org.apache.catalina.LifecycleState;
 import org.apache.catalina.util.LifecycleMBeanBase;
 import org.apache.tomcat.util.compat.JreCompat;
 import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.threads.VirtualThreadExecutor;
 
 /**
  * An executor that uses a new virtual thread for each task.
  */
-public class VirtualThreadExecutor extends LifecycleMBeanBase implements Executor {
+public class StandardVirtualThreadExecutor extends LifecycleMBeanBase implements Executor {
 
-    private static final StringManager sm = StringManager.getManager(VirtualThreadExecutor.class);
-
-    private final JreCompat jreCompat = JreCompat.getInstance();
+    private static final StringManager sm = StringManager.getManager(StandardVirtualThreadExecutor.class);
 
     private String name;
-    private Object threadBuilder;
+    private java.util.concurrent.Executor executor;
     private String namePrefix;
 
     public void setName(String name) {
@@ -57,13 +56,17 @@ public class VirtualThreadExecutor extends LifecycleMBeanBase implements Executo
 
     @Override
     public void execute(Runnable command) {
-        JreCompat.getInstance().threadBuilderStart(threadBuilder, command);
+        if (executor == null) {
+            throw new IllegalStateException(sm.getString("standardVirtualThreadExecutor.notStarted"));
+        } else {
+            executor.execute(command);
+        }
     }
 
 
     @Override
     public void execute(Runnable command, long timeout, TimeUnit unit) {
-        JreCompat.getInstance().threadBuilderStart(threadBuilder, command);
+        execute(command);
     }
 
 
@@ -71,19 +74,19 @@ public class VirtualThreadExecutor extends LifecycleMBeanBase implements Executo
     protected void initInternal() throws LifecycleException {
         super.initInternal();
         if (!JreCompat.isJre21Available()) {
-            throw new LifecycleException(sm.getString("virtualThreadExecutor.noVirtualThreads"));
+            throw new LifecycleException(sm.getString("standardVirtualThreadExecutor.noVirtualThreads"));
         }
     }
 
     @Override
     protected void startInternal() throws LifecycleException {
-        threadBuilder = jreCompat.createVirtualThreadBuilder(getNamePrefix());
+        executor = new VirtualThreadExecutor(getNamePrefix());
         setState(LifecycleState.STARTING);
     }
 
     @Override
     protected void stopInternal() throws LifecycleException {
-        threadBuilder = null;
+        executor = null;
         setState(LifecycleState.STOPPING);
     }
 
diff --git a/java/org/apache/tomcat/util/net/AbstractEndpoint.java b/java/org/apache/tomcat/util/net/AbstractEndpoint.java
index 0686b516a5..423403e31f 100644
--- a/java/org/apache/tomcat/util/net/AbstractEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AbstractEndpoint.java
@@ -56,6 +56,7 @@ import org.apache.tomcat.util.threads.ResizableExecutor;
 import org.apache.tomcat.util.threads.TaskQueue;
 import org.apache.tomcat.util.threads.TaskThreadFactory;
 import org.apache.tomcat.util.threads.ThreadPoolExecutor;
+import org.apache.tomcat.util.threads.VirtualThreadExecutor;
 
 /**
  * @param <S> The type used by the socket wrapper associated with this endpoint.
@@ -629,6 +630,15 @@ public abstract class AbstractEndpoint<S,U> {
     public Executor getExecutor() { return executor; }
 
 
+    private boolean useVirtualThreads = false;
+    public void setUseVirtualThreads(boolean useVirtualThreads) {
+        this.useVirtualThreads = useVirtualThreads;
+    }
+    public boolean getVirtualThreads() {
+        return useVirtualThreads;
+    }
+
+
     /**
      * Server socket port.
      */
@@ -1064,12 +1074,17 @@ public abstract class AbstractEndpoint<S,U> {
 
     public void createExecutor() {
         internalExecutor = true;
-        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);
+        if (useVirtualThreads) {
+            executor = new VirtualThreadExecutor(getName() + "-exec-");
+        } 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);
+        }
     }
 
+
     public void shutdownExecutor() {
         Executor executor = this.executor;
         if (executor != null && internalExecutor) {
diff --git a/java/org/apache/tomcat/util/threads/VirtualThreadExecutor.java b/java/org/apache/tomcat/util/threads/VirtualThreadExecutor.java
new file mode 100644
index 0000000000..93a00f8d42
--- /dev/null
+++ b/java/org/apache/tomcat/util/threads/VirtualThreadExecutor.java
@@ -0,0 +1,40 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tomcat.util.threads;
+
+import java.util.concurrent.Executor;
+
+import org.apache.tomcat.util.compat.JreCompat;
+
+/**
+ * An executor that uses a new virtual thread for each task.
+ */
+public class VirtualThreadExecutor implements Executor {
+
+    private final JreCompat jreCompat = JreCompat.getInstance();
+
+    private Object threadBuilder;
+
+    public VirtualThreadExecutor(String namePrefix) {
+        threadBuilder = jreCompat.createVirtualThreadBuilder(namePrefix);
+    }
+
+    @Override
+    public void execute(Runnable command) {
+        jreCompat.threadBuilderStart(threadBuilder, command);
+    }
+}
\ No newline at end of file
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 52b9fd2a5c..2c4aa6fc53 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -108,8 +108,8 @@
   <subsection name="Catalina">
     <changelog>
       <add>
-        Add <code>org.apache.catalina.core.VirtualThreadExecutor</code>, a
-        virtual thread based executor that may be used with one or more
+        Add <code>org.apache.catalina.core.StandardVirtualThreadExecutor</code>,
+        a virtual thread based executor that may be used with one or more
         Connectors to process requests received by those Connectors using
         virtual threads. This Executor requires a minimum Java version of Java
         21. (markt)
diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml
index 9436a766fe..8492451a2e 100644
--- a/webapps/docs/config/ajp.xml
+++ b/webapps/docs/config/ajp.xml
@@ -565,6 +565,13 @@
       <code>false</code>.</p>
     </attribute>
 
+    <attribute name="useVirtualThreads" required="false">
+      <p>(bool) Use this attribute to enable or disable usage of virtual threads
+      with the internal executor. If an executor is associated with this
+      connector, this attribute is ignored. The default value is
+      <code>false</code>.</p>
+    </attribute>
+
   </attributes>
 
   </subsection>
diff --git a/webapps/docs/config/executor.xml b/webapps/docs/config/executor.xml
index 59cf023605..b5e48099f5 100644
--- a/webapps/docs/config/executor.xml
+++ b/webapps/docs/config/executor.xml
@@ -128,8 +128,8 @@
   <p>This implemtenation uses a new virtual thread to execute each task assigned to the Executor. This Executor requires
      a minimum Java version of Java 21.</p>
 
-  <p>The <code>className</code> attribute must be <code>org.apache.catalina.core.VirtualThreadExecutor</code> to use
-     this implementation.</p>
+  <p>The <code>className</code> attribute must be <code>org.apache.catalina.core.StandardVirtualThreadExecutor</code> to
+     use this implementation.</p>
 
   <p>The virtual thread implementation supports the follow attributes:</p>
 
diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
index 6edee2ad81..ca53ac4f5f 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -741,6 +741,13 @@
       Internet-Draft</a>. The default value is <code>true</code>.</p>
     </attribute>
 
+    <attribute name="useVirtualThreads" required="false">
+      <p>(bool) Use this attribute to enable or disable usage of virtual threads
+      with the internal executor. If an executor is associated with this
+      connector, this attribute is ignored. The default value is
+      <code>false</code>.</p>
+    </attribute>
+
   </attributes>
 
   </subsection>


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