diff --git a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRegionFactoryInitiator.java b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRegionFactoryInitiator.java index c6ab8087430fde..439eb13a5b77fc 100644 --- a/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRegionFactoryInitiator.java +++ b/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/service/QuarkusRegionFactoryInitiator.java @@ -3,6 +3,9 @@ import static java.lang.Boolean.FALSE; import java.util.Map; +import java.util.concurrent.Executor; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Supplier; import org.hibernate.boot.registry.StandardServiceInitiator; import org.hibernate.cache.internal.NoCachingRegionFactory; @@ -12,6 +15,10 @@ import org.hibernate.service.spi.ServiceRegistryImplementor; import org.infinispan.quarkus.hibernate.cache.QuarkusInfinispanRegionFactory; +import io.quarkus.arc.Arc; +import io.quarkus.arc.InstanceHandle; +import io.vertx.core.Vertx; + public final class QuarkusRegionFactoryInitiator implements StandardServiceInitiator { public static final QuarkusRegionFactoryInitiator INSTANCE = new QuarkusRegionFactoryInitiator(); @@ -44,7 +51,38 @@ public RegionFactory initiateService(Map configurationValues, ServiceRegistryImp } } - return new QuarkusInfinispanRegionFactory(); + return new QuarkusInfinispanRegionFactory(getCacheExecutor()); + } + + private Supplier getCacheExecutor() { + String propertyName = "io.quarkus.hibernate-orm.2lc.caffeineexecutor"; + //Undocumented property for now: TODO benchmark and decide if it's worth to expose as user facing options? + final String executorStrategy = System.getProperty(propertyName, "ON_EVENTLOOP"); + switch (executorStrategy) { + case "ON_EVENTLOOP": //We expect this to perform best, so it's the current default in Quarkus. + return () -> getVertxCacheExecutor(); + case "INLINE": + return () -> Runnable::run; + case "ON_FORKJOIN": + return () -> ForkJoinPool.commonPool(); //default in Caffeine: same as returning null + default: + throw new IllegalArgumentException( + "Unrecognized property value for '" + propertyName + "'='" + executorStrategy + "'"); + } + //For a full explanation, see https://github.com/quarkusio/quarkus/issues/32317#issuecomment-1492698253 + } + + private static Executor getVertxCacheExecutor() { + final Vertx vertx = retrieveVertxInstance(); + return vertx.nettyEventLoopGroup(); + } + + private static Vertx retrieveVertxInstance() { + InstanceHandle vertxHandle = Arc.container().instance(Vertx.class); + if (!vertxHandle.isAvailable()) { + throw new IllegalStateException("No Vert.x instance has been registered in ArC ?"); + } + return vertxHandle.get(); } }