Asynchronously create EmbeddedCacheManager when JDBC_PING2 not required
Closes #34313 Signed-off-by: Ryan Emerson <remerson@redhat.com>
This commit is contained in:
parent
4e540fa2a7
commit
ba51140a25
1 changed files with 44 additions and 14 deletions
|
@ -28,6 +28,7 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -52,6 +53,7 @@ import org.infinispan.configuration.global.ShutdownHookBehavior;
|
|||
import org.infinispan.configuration.parsing.ConfigurationBuilderHolder;
|
||||
import org.infinispan.configuration.parsing.ParserRegistry;
|
||||
import org.infinispan.manager.DefaultCacheManager;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.infinispan.metrics.config.MicrometerMeterRegisterConfigurationBuilder;
|
||||
import org.infinispan.persistence.remote.configuration.ExhaustedAction;
|
||||
import org.infinispan.persistence.remote.configuration.RemoteStoreConfigurationBuilder;
|
||||
|
@ -110,12 +112,21 @@ public class CacheManagerFactory {
|
|||
|
||||
private static final Logger logger = Logger.getLogger(CacheManagerFactory.class);
|
||||
|
||||
private final CompletableFuture<EmbeddedCacheManager> cacheManagerFuture;
|
||||
private final CompletableFuture<RemoteCacheManager> remoteCacheManagerFuture;
|
||||
private final String config;
|
||||
private volatile DefaultCacheManager cacheManager;
|
||||
private final Function<EntityManager, EmbeddedCacheManager> jdbcCacheManagerFunction;
|
||||
private volatile EmbeddedCacheManager cacheManager;
|
||||
|
||||
public CacheManagerFactory(String config) {
|
||||
this.config = config;
|
||||
ConfigurationBuilderHolder builder = new ParserRegistry().parse(config);
|
||||
if (!isJdbcPingRequired(builder)) {
|
||||
cacheManagerFuture = CompletableFuture.supplyAsync(() -> startEmbeddedCacheManager(builder, null));
|
||||
jdbcCacheManagerFunction = null;
|
||||
} else {
|
||||
cacheManagerFuture = null;
|
||||
jdbcCacheManagerFunction = em -> startEmbeddedCacheManager(builder, em);
|
||||
}
|
||||
|
||||
if (InfinispanUtils.isRemoteInfinispan()) {
|
||||
logger.debug("Remote Cache feature is enabled");
|
||||
this.remoteCacheManagerFuture = CompletableFuture.supplyAsync(this::startRemoteCacheManager);
|
||||
|
@ -125,11 +136,32 @@ public class CacheManagerFactory {
|
|||
}
|
||||
}
|
||||
|
||||
public DefaultCacheManager getOrCreateEmbeddedCacheManager(KeycloakSession keycloakSession) {
|
||||
private static boolean isJdbcPingRequired(ConfigurationBuilderHolder builder) {
|
||||
if (InfinispanUtils.isRemoteInfinispan())
|
||||
return false;
|
||||
|
||||
var transportConfig = builder.getGlobalConfigurationBuilder().transport();
|
||||
if (transportConfig.getTransport() == null)
|
||||
return false;
|
||||
|
||||
String transportStack = Configuration.getRawValue("kc.cache-stack");
|
||||
if (transportStack != null && !isJdbcPingStack(transportStack))
|
||||
return false;
|
||||
|
||||
var stackXmlAttribute = transportConfig.defaultTransport().attributes().attribute(STACK);
|
||||
return !stackXmlAttribute.isModified() || isJdbcPingStack(stackXmlAttribute.get());
|
||||
}
|
||||
|
||||
public EmbeddedCacheManager getOrCreateEmbeddedCacheManager(KeycloakSession keycloakSession) {
|
||||
if (cacheManagerFuture != null)
|
||||
return join(cacheManagerFuture);
|
||||
|
||||
if (cacheManager == null) {
|
||||
synchronized (this) {
|
||||
if (cacheManager == null)
|
||||
cacheManager = startEmbeddedCacheManager(keycloakSession);
|
||||
if (cacheManager == null) {
|
||||
EntityManager em = keycloakSession.getProvider(JpaConnectionProvider.class).getEntityManager();
|
||||
cacheManager = jdbcCacheManagerFunction.apply(em);
|
||||
}
|
||||
}
|
||||
}
|
||||
return cacheManager;
|
||||
|
@ -286,9 +318,8 @@ public class CacheManagerFactory {
|
|||
admin.reindexCache(cacheName);
|
||||
}
|
||||
|
||||
private DefaultCacheManager startEmbeddedCacheManager(KeycloakSession keycloakSession) {
|
||||
private EmbeddedCacheManager startEmbeddedCacheManager(ConfigurationBuilderHolder builder, EntityManager em) {
|
||||
logger.info("Starting Infinispan embedded cache manager");
|
||||
ConfigurationBuilderHolder builder = new ParserRegistry().parse(config);
|
||||
|
||||
// We must disable the Infinispan default ShutdownHook as we manage the EmbeddedCacheManager lifecycle explicitly
|
||||
// with #shutdown and multiple calls to EmbeddedCacheManager#stop can lead to Exceptions being thrown
|
||||
|
@ -322,7 +353,7 @@ public class CacheManagerFactory {
|
|||
} else {
|
||||
// embedded mode!
|
||||
if (builder.getNamedConfigurationBuilders().entrySet().stream().anyMatch(c -> c.getValue().clustering().cacheMode().isClustered())) {
|
||||
configureTransportStack(builder, keycloakSession);
|
||||
configureTransportStack(builder, em);
|
||||
configureRemoteStores(builder);
|
||||
}
|
||||
configureCacheMaxCount(builder, CachingOptions.CLUSTERED_MAX_COUNT_CACHES);
|
||||
|
@ -368,7 +399,7 @@ public class CacheManagerFactory {
|
|||
return Integer.getInteger("kc.cache-ispn-start-timeout", 120);
|
||||
}
|
||||
|
||||
private void configureTransportStack(ConfigurationBuilderHolder builder, KeycloakSession keycloakSession) {
|
||||
private static void configureTransportStack(ConfigurationBuilderHolder builder, EntityManager em) {
|
||||
var transportConfig = builder.getGlobalConfigurationBuilder().transport();
|
||||
if (Configuration.isTrue(CachingOptions.CACHE_EMBEDDED_MTLS_ENABLED_PROPERTY)) {
|
||||
validateTlsAvailable(transportConfig.build());
|
||||
|
@ -405,7 +436,6 @@ public class CacheManagerFactory {
|
|||
stackXmlAttribute.isModified() ? stackXmlAttribute.get() : "jdbc-ping-udp";
|
||||
var udp = stackName.endsWith("udp");
|
||||
|
||||
EntityManager em = keycloakSession.getProvider(JpaConnectionProvider.class).getEntityManager();
|
||||
var tableName = JpaUtils.getTableNameForNativeQuery("JGROUPS_PING", em);
|
||||
var attributes = Map.of(
|
||||
// Leave initialize_sql blank as table is already created by Keycloak
|
||||
|
@ -429,16 +459,16 @@ public class CacheManagerFactory {
|
|||
transportConfig.defaultTransport().stack(stackName);
|
||||
}
|
||||
|
||||
private void warnDeprecatedCloudStack(String stackName) {
|
||||
private static void warnDeprecatedCloudStack(String stackName) {
|
||||
switch (stackName) {
|
||||
case "azure":
|
||||
case "ec2":
|
||||
case "google":
|
||||
logger.warnf("Stack '%s' is deprecated. We recommend to use 'jdbc-ping' instead", stackName);
|
||||
Logger.getLogger(CacheManagerFactory.class).warnf("Stack '%s' is deprecated. We recommend to use 'jdbc-ping' instead", stackName);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isJdbcPingStack(String stackName) {
|
||||
private static boolean isJdbcPingStack(String stackName) {
|
||||
return "jdbc-ping".equals(stackName) || "jdbc-ping-udp".equals(stackName);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue