From 6b390281fea37c2633cdb47c2f142cd2e3bf85f3 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Wed, 5 Apr 2023 20:40:52 +0100 Subject: [PATCH] Ensure ORM's 2LC Caffeine instance runs eviction tasks on the eventloop by default --- .../QuarkusRegionFactoryInitiator.java | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) 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(); } }