diff --git a/docs/documentation/release_notes/topics/26_1_0.adoc b/docs/documentation/release_notes/topics/26_1_0.adoc index cd8172c95f1..80b00b3043e 100644 --- a/docs/documentation/release_notes/topics/26_1_0.adoc +++ b/docs/documentation/release_notes/topics/26_1_0.adoc @@ -15,7 +15,7 @@ See the https://www.keycloak.org/server/caching[Configuring distributed caches] = Virtual Threads enabled for Infinispan and JGroups thread pools -Starting from this release, {project_name} automatically enables the virtual thread pool support in both the embedded Infinispan and JGroups when running on OpenJDK 21. +Starting from this release, {project_name} automatically enables the virtual thread pool support in both the embedded Infinispan and JGroups when running on OpenJDK 21 for environments with at least 2 CPU cores available. This removes the need to configure the JGroups thread pool, the need to align the JGroups thread pool with the HTTP worker thread pool, and reduces the overall memory footprint. = OpenTelemetry Tracing supported diff --git a/docs/guides/high-availability/concepts-threads.adoc b/docs/guides/high-availability/concepts-threads.adoc index baaac0932c5..f707a280f14 100644 --- a/docs/guides/high-availability/concepts-threads.adoc +++ b/docs/guides/high-availability/concepts-threads.adoc @@ -17,7 +17,7 @@ For a configuration where this is applied, visit <@links.ha id="deploy-keycloak- // remove this paragraph once OpenJDK 17 is no longer supported on the server side. // https://github.com/keycloak/keycloak/issues/31101 -JGroups communications, which is used in single-site setups for the communication between {project_name} nodes, benefits from the use of virtual threads which are available in OpenJDK 21. +JGroups communications, which is used in single-site setups for the communication between {project_name} nodes, benefits from the use of virtual threads which are available in OpenJDK 21 when at least two cores are available for {project_name}. This reduces the memory usage and removes the need to configure thread pool sizes. Therefore, the use of OpenJDK 21 is recommended. diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java index 76d301fd052..d22f394e997 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java @@ -53,21 +53,43 @@ public class KeycloakMain implements QuarkusApplication { private static final String INFINISPAN_VIRTUAL_THREADS_PROP = "org.infinispan.threads.virtual"; + public static final int MIN_VT_POOL_SIZE = 2; + static { // enable Infinispan and JGroups virtual threads by default - if (System.getProperty(INFINISPAN_VIRTUAL_THREADS_PROP) == null) { + if (System.getProperty(INFINISPAN_VIRTUAL_THREADS_PROP) == null && getParallelism() >= MIN_VT_POOL_SIZE) { System.setProperty(INFINISPAN_VIRTUAL_THREADS_PROP, "true"); } } public static void main(String[] args) { ensureForkJoinPoolThreadFactoryHasBeenSetToQuarkus(); + ensureVirtualThreadsParallelism(); System.setProperty("kc.version", Version.VERSION); main(args, new Picocli()); } + private static void ensureVirtualThreadsParallelism() { + if (Boolean.parseBoolean(System.getProperty(INFINISPAN_VIRTUAL_THREADS_PROP))) { + if (getParallelism() < MIN_VT_POOL_SIZE) { + throw new RuntimeException("To be able to use Infinispan/JGroups virtual threads, you need to set the Java system property jdk.virtualThreadScheduler.parallelism to at least " + MIN_VT_POOL_SIZE); + } + } + } + + private static int getParallelism() { + int parallelism; + String parallelismValue = System.getProperty("jdk.virtualThreadScheduler.parallelism"); + if (parallelismValue != null) { + parallelism = Integer.parseInt(parallelismValue); + } else { + parallelism = Runtime.getRuntime().availableProcessors(); + } + return parallelism; + } + public static void main(String[] args, Picocli picocli) { List cliArgs = null; try {