This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push: new c382352b35 Add useVirtualThreads attribute to endpoints. c382352b35 is described below commit c382352b353bcabad86a646ad02d87108a46e807 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 | 2 ++ ...tor.java => StandardVirtualThreadExecutor.java} | 18 ++++++++--- .../apache/tomcat/util/net/AbstractEndpoint.java | 23 +++++++++++--- .../tomcat/util/threads/VirtualThreadExecutor.java | 36 ++++++++++++++++++++++ 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, 88 insertions(+), 13 deletions(-) diff --git a/java/org/apache/catalina/core/LocalStrings.properties b/java/org/apache/catalina/core/LocalStrings.properties index 13cf4491ec..cbc7e4999b 100644 --- a/java/org/apache/catalina/core/LocalStrings.properties +++ b/java/org/apache/catalina/core/LocalStrings.properties @@ -280,6 +280,8 @@ standardService.stop.name=Stopping service [{0}] standardThreadExecutor.notStarted=The executor has not been started +standardVirtualThreadExecutor.notStarted=The executor has not been started + standardWrapper.allocate=Error allocating a servlet instance standardWrapper.allocateException=Allocate exception for servlet [{0}] standardWrapper.deallocateException=Deallocate exception for servlet [{0}] diff --git a/java/org/apache/catalina/core/VirtualThreadExecutor.java b/java/org/apache/catalina/core/StandardVirtualThreadExecutor.java similarity index 75% rename from java/org/apache/catalina/core/VirtualThreadExecutor.java rename to java/org/apache/catalina/core/StandardVirtualThreadExecutor.java index 98fa1edee4..7398655494 100644 --- a/java/org/apache/catalina/core/VirtualThreadExecutor.java +++ b/java/org/apache/catalina/core/StandardVirtualThreadExecutor.java @@ -20,14 +20,18 @@ import org.apache.catalina.Executor; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleState; import org.apache.catalina.util.LifecycleMBeanBase; +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(StandardVirtualThreadExecutor.class); private String name; - private Thread.Builder threadBuilder; + private java.util.concurrent.Executor executor; private String namePrefix; public void setName(String name) { @@ -49,19 +53,23 @@ public class VirtualThreadExecutor extends LifecycleMBeanBase implements Executo @Override public void execute(Runnable command) { - threadBuilder.start(command); + if (executor == null) { + throw new IllegalStateException(sm.getString("standardVirtualThreadExecutor.notStarted")); + } else { + executor.execute(command); + } } @Override protected void startInternal() throws LifecycleException { - threadBuilder = Thread.ofVirtual().name(getNamePrefix(), 0); + 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 d33b33a17f..8698dedf92 100644 --- a/java/org/apache/tomcat/util/net/AbstractEndpoint.java +++ b/java/org/apache/tomcat/util/net/AbstractEndpoint.java @@ -61,6 +61,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. @@ -743,6 +744,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; + } + + /** * External Executor based thread pool for utility tasks. */ @@ -1169,12 +1179,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..0e177fe861 --- /dev/null +++ b/java/org/apache/tomcat/util/threads/VirtualThreadExecutor.java @@ -0,0 +1,36 @@ +/* + * 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; + +/** + * An executor that uses a new virtual thread for each task. + */ +public class VirtualThreadExecutor implements Executor { + + private Thread.Builder threadBuilder; + + public VirtualThreadExecutor(String namePrefix) { + threadBuilder = Thread.ofVirtual().name(namePrefix, 0); + } + + @Override + public void execute(Runnable command) { + threadBuilder.start(command); + } +} \ No newline at end of file diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 86996037d1..d5a96ce78c 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -130,8 +130,8 @@ (markt) </scode> <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. (markt) </add> diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml index b6f2a22a83..bfc30554d6 100644 --- a/webapps/docs/config/ajp.xml +++ b/webapps/docs/config/ajp.xml @@ -575,6 +575,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 abffc9f5d1..807e918467 100644 --- a/webapps/docs/config/executor.xml +++ b/webapps/docs/config/executor.xml @@ -127,8 +127,8 @@ <p>This implemtenation uses a new virtual thread to execute each task assigned to the Executor.</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 047959c754..1386e94478 100644 --- a/webapps/docs/config/http.xml +++ b/webapps/docs/config/http.xml @@ -705,6 +705,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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org