diff --git a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/ArchitectureDocs.java b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/ArchitectureDocs.java index 5edfd89fbf5..d3ad64fe497 100644 --- a/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/ArchitectureDocs.java +++ b/documentation/jetty/modules/code/examples/src/main/java/org/eclipse/jetty/docs/programming/ArchitectureDocs.java @@ -15,6 +15,9 @@ package org.eclipse.jetty.docs.programming; import java.util.concurrent.Executors; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP; +import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.VirtualThreadPool; @@ -26,9 +29,26 @@ public class ArchitectureDocs { // tag::queuedVirtual[] QueuedThreadPool threadPool = new QueuedThreadPool(); + + // Simple, unlimited, virtual thread Executor. threadPool.setVirtualThreadsExecutor(Executors.newVirtualThreadPerTaskExecutor()); + // Configurable, bounded, virtual thread executor (preferred). + VirtualThreadPool virtualExecutor = new VirtualThreadPool(); + virtualExecutor.setMaxThreads(128); + threadPool.setVirtualThreadsExecutor(virtualExecutor); + + // For server-side usage. Server server = new Server(threadPool); + + // Simple client-side usage. + HttpClient client = new HttpClient(); + client.setExecutor(threadPool); + + // Client-side usage with explicit HttpClientTransport. + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setExecutor(threadPool); + HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)); // end::queuedVirtual[] } @@ -38,8 +58,21 @@ public class ArchitectureDocs VirtualThreadPool threadPool = new VirtualThreadPool(); // Limit the max number of current virtual threads. threadPool.setMaxThreads(200); + // Track, with details, virtual threads usage. + threadPool.setTracking(true); + threadPool.setDetailedDump(true); + // For server-side usage. Server server = new Server(threadPool); + + // Simple client-side usage. + HttpClient client = new HttpClient(); + client.setExecutor(threadPool); + + // Client-side usage with explicit HttpClientTransport. + ClientConnector clientConnector = new ClientConnector(); + clientConnector.setExecutor(threadPool); + HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)); // end::virtualVirtual[] } } diff --git a/documentation/jetty/modules/operations-guide/pages/modules/standard.adoc b/documentation/jetty/modules/operations-guide/pages/modules/standard.adoc index d3992234c71..95c020f899c 100644 --- a/documentation/jetty/modules/operations-guide/pages/modules/standard.adoc +++ b/documentation/jetty/modules/operations-guide/pages/modules/standard.adoc @@ -714,7 +714,6 @@ See also the xref:server/index.adoc#threadpool[section about configuring the thr The `threadpool-all-virtual` module allows you to configure the server-wide thread pool, similarly to what you can do with the <> Jetty module, so that all threads are virtual threads, introduced as an official feature since Java 21. CAUTION: Only use this module if you are using Java 21 or later. -If you are using Java 19 or Java 20, use the <> Jetty module instead. The module properties to configure the thread pool are: @@ -724,17 +723,7 @@ include::{jetty-home}/modules/threadpool-all-virtual.mod[tags=documentation] The property `jetty.threadpool.maxThreads` limits, using a `Semaphore`, the number of current virtual threads in use. -Limiting the number of current virtual threads helps to limit resource usage in applications, especially in case of load spikes. -When an unlimited number of virtual threads is allowed, the server might be brought down due to resource (typically memory) exhaustion. - -[CAUTION] -==== -Even when using virtual threads, Jetty uses non-blocking I/O, and dedicates a thread to each `java.nio.channels.Selector` to perform the `Selector.select()` operation. - -Currently (up to Java 22), calling `Selector.select()` from a virtual thread pins the carrier thread. - -When using the `threadpool-all-virtual` Jetty module, if you have `N` selectors, then `N` carrier threads will be pinned by the virtual threads calling `Selector.select()`, possibly making your system less efficient, and at worst locking up the entire system if there are no carrier threads available to run virtual threads. -==== +Please refer to the xref:programming-guide:arch/threads.adoc#thread-pool-virtual-threads[virtual threads section] of the Jetty Threading Architecture for more information about virtual threads and their pitfalls. [[threadpool-virtual]] == Module `threadpool-virtual` diff --git a/documentation/jetty/modules/programming-guide/pages/arch/threads.adoc b/documentation/jetty/modules/programming-guide/pages/arch/threads.adoc index 1fb7dff1d2b..39f4b756503 100644 --- a/documentation/jetty/modules/programming-guide/pages/arch/threads.adoc +++ b/documentation/jetty/modules/programming-guide/pages/arch/threads.adoc @@ -269,6 +269,35 @@ Defaulting the number of reserved threads to zero ensures that the <