Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment with fully virtual VirtualThreadPool #11501

Merged
merged 14 commits into from
May 7, 2024
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">

<Configure>
<New id="threadPool" class="org.eclipse.jetty.util.thread.VirtualThreadPool">
<Set name="name" property="jetty.threadPool.namePrefix" />
</New>

<Call class="org.slf4j.LoggerFactory" name="getLogger">
<Arg>org.eclipse.jetty</Arg>
<Call name="info">
<Arg>All Virtual threads are enabled.</Arg>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be more clear as in "Virtual threads enabled, using only virtual threads".

Also the file name should replace "-all-" with "-full-" or "-only-".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer "all". "full" is confusing when pools are involved. What does it mean to have a full non pooling pool? "Only" is ok, but it is just as easy to say "the threads used are all virtual", as it is to say "the threads used are only virtual". However, "only virtual" can be taken as a pejorative (which in this case might be appropriate :), so I prefer "all"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like jetty-threadpool-only-virtual.xml

</Call>
</Call>
</Configure>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[description]
Enables and configures the Server ThreadPool with support for virtual threads to be used for all threads.
There is some risk of CPU pinning with this configuration. Only supported in Java 21 or later.

[depends]
logging

[provides]
threadpool

[xml]
etc/jetty-threadpool-all-virtual.xml

[ini-template]
# tag::documentation[]
## Platform threads name prefix.
#jetty.threadPool.namePrefix=vtp<hashCode>

# end::documentation[]
gregw marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[description]
Enables and configures the Server ThreadPool with support for virtual threads in Java 21 or later.
Enables and configures the Server ThreadPool with support for virtual threads to be used for blocking tasks.
Only supported in Java 21 or later.

[depends]
logging
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,9 @@
public class VirtualThreads
{
private static final Logger LOG = LoggerFactory.getLogger(VirtualThreads.class);
private static final Executor executor = probeVirtualThreadExecutor();
private static final ThreadFactoryExecutor executor = getNamedVirtualThreadFactoryExecutor(null);
private static final Method isVirtualThread = probeIsVirtualThread();

private static Executor probeVirtualThreadExecutor()
{
try
{
return (Executor)Executors.class.getMethod("newVirtualThreadPerTaskExecutor").invoke(null);
}
catch (Throwable x)
{
return null;
}
}

private static Method probeIsVirtualThread()
{
try
Expand Down Expand Up @@ -126,14 +114,41 @@ public static boolean isVirtualThread()
* @return a virtual threads {@code Executor} that will name the virtual threads according to the provided name prefix.
*/
public static Executor getNamedVirtualThreadsExecutor(String namePrefix)
{
return getNamedVirtualThreadFactoryExecutor(namePrefix);
}

/**
* Get a virtual threads {@code Executor} that names the virtual threads according to the provided name prefix.
* While named virtual threads enable observability they do also incur a minor performance penalty.
*
* @param namePrefix the prefix to use for the name of the virtual threads
* @return a virtual threads {@code Executor} that will name the virtual threads according to the provided name prefix.
*/
public static ThreadFactoryExecutor getNamedVirtualThreadFactoryExecutor(String namePrefix)
{
try
{
Class<?> builderClass = Class.forName("java.lang.Thread$Builder");
Object threadBuilder = Thread.class.getMethod("ofVirtual").invoke(null);
threadBuilder = builderClass.getMethod("name", String.class, long.class).invoke(threadBuilder, namePrefix, 0L);
if (StringUtil.isNotBlank(namePrefix))
threadBuilder = builderClass.getMethod("name", String.class, long.class).invoke(threadBuilder, namePrefix, 0L);
ThreadFactory factory = (ThreadFactory)builderClass.getMethod("factory").invoke(threadBuilder);
return (Executor)Executors.class.getMethod("newThreadPerTaskExecutor", ThreadFactory.class).invoke(null, factory);
Executor executor = (Executor)Executors.class.getMethod("newThreadPerTaskExecutor", ThreadFactory.class).invoke(null, factory);
return new ThreadFactoryExecutor()
{
@Override
public void execute(Runnable command)
{
executor.execute(command);
}

@Override
public Thread newThread(Runnable r)
{
return factory.newThread(r);
}
};
}
catch (Throwable x)
{
Expand All @@ -150,6 +165,15 @@ public static Executor getDefaultVirtualThreadsExecutor()
return executor;
}

/**
* Get a default virtual thread per task {@code Executor}.
* @return a default virtual thread per task {@code Executor}
*/
public static ThreadFactoryExecutor getDefaultVirtualThreadFactoryExecutor()
{
return executor;
}

/**
* @param executor the {@code Executor} to obtain a virtual threads {@code Executor} from
* @return a virtual threads {@code Executor} obtained from the given {@code Executor}
Expand Down Expand Up @@ -233,4 +257,7 @@ default void setUseVirtualThreads(boolean useVirtualThreads)
private VirtualThreads()
{
}

public interface ThreadFactoryExecutor extends ThreadFactory, Executor
gregw marked this conversation as resolved.
Show resolved Hide resolved
{}
}
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ public void setReservedThreads(int reservedThreads)
}

/**
* @return the name of the this thread pool
* @return the name of this thread pool
*/
@ManagedAttribute("name of the thread pool")
public String getName()
Expand All @@ -460,7 +460,7 @@ public String getName()
/**
* <p>Sets the name of this thread pool, used as a prefix for the thread names.</p>
*
* @param name the name of the this thread pool
* @param name the name of this thread pool
*/
public void setName(String name)
{
Expand Down Expand Up @@ -835,7 +835,7 @@ public void join() throws InterruptedException

while (isStopping())
{
Thread.sleep(1);
Thread.onSpinWait();
}
}

Expand Down
Loading
Loading