Skip to content

Commit

Permalink
Merge pull request #30000 from gwenneg/#29934-config
Browse files Browse the repository at this point in the history
Change quarkus-cache config phase from BUILD_TIME to RUN_TIME
  • Loading branch information
gwenneg authored Jan 9, 2023
2 parents c4da818 + 71246e3 commit e579cd2
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ public class CacheDeploymentConstants {
// Annotations parameters.
public static final String CACHE_NAME_PARAM = "cacheName";

// Caffeine.
public static final String CAFFEINE_CACHE_TYPE = "caffeine";

private static DotName dotName(Class<?> annotationClass) {
return DotName.createSimple(annotationClass.getName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import static io.quarkus.cache.deployment.CacheDeploymentConstants.INTERCEPTOR_BINDING_CONTAINERS;
import static io.quarkus.cache.deployment.CacheDeploymentConstants.MULTI;
import static io.quarkus.cache.deployment.CacheDeploymentConstants.REGISTER_REST_CLIENT;
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;
import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT;
import static io.quarkus.runtime.metrics.MetricsFactory.MICROMETER;
import static java.util.stream.Collectors.toList;
import static org.jboss.jandex.AnnotationTarget.Kind.METHOD;
Expand Down Expand Up @@ -54,13 +54,8 @@
import io.quarkus.cache.deployment.exception.VoidReturnTypeTargetException;
import io.quarkus.cache.runtime.CacheInvalidateAllInterceptor;
import io.quarkus.cache.runtime.CacheInvalidateInterceptor;
import io.quarkus.cache.runtime.CacheManagerRecorder;
import io.quarkus.cache.runtime.CacheResultInterceptor;
import io.quarkus.cache.runtime.caffeine.CaffeineCacheBuildRecorder;
import io.quarkus.cache.runtime.caffeine.CaffeineCacheInfo;
import io.quarkus.cache.runtime.caffeine.metrics.MetricsInitializer;
import io.quarkus.cache.runtime.caffeine.metrics.MicrometerMetricsInitializer;
import io.quarkus.cache.runtime.caffeine.metrics.NoOpMetricsInitializer;
import io.quarkus.cache.runtime.noop.NoOpCacheBuildRecorder;
import io.quarkus.deployment.Feature;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
Expand Down Expand Up @@ -230,39 +225,26 @@ private List<Throwable> validateKeyGeneratorsDefaultConstructor(CombinedIndexBui
}

@BuildStep
@Record(STATIC_INIT)
SyntheticBeanBuildItem configureCacheManagerSyntheticBean(CacheNamesBuildItem cacheNames, CacheConfig config,
CaffeineCacheBuildRecorder caffeineRecorder, NoOpCacheBuildRecorder noOpRecorder,
Optional<MetricsCapabilityBuildItem> metricsCapability) {
@Record(RUNTIME_INIT)
SyntheticBeanBuildItem configureCacheManagerSyntheticBean(CacheNamesBuildItem cacheNames,
CacheManagerRecorder cacheManagerRecorder, Optional<MetricsCapabilityBuildItem> metricsCapability) {

boolean micrometerSupported = metricsCapability.isPresent() && metricsCapability.get().metricsSupported(MICROMETER);

Supplier<CacheManager> cacheManagerSupplier;
if (config.enabled) {
switch (config.type) {
case CacheDeploymentConstants.CAFFEINE_CACHE_TYPE:
Set<CaffeineCacheInfo> cacheInfos = CaffeineCacheInfoBuilder.build(cacheNames.getNames(), config);
MetricsInitializer metricsInitializer = getMetricsInitializer(metricsCapability);
cacheManagerSupplier = caffeineRecorder.getCacheManagerSupplier(cacheInfos, metricsInitializer);
break;
default:
throw new DeploymentException("Unknown cache type: " + config.type);
}
if (micrometerSupported) {
cacheManagerSupplier = cacheManagerRecorder.getCacheManagerSupplierWithMicrometerMetrics(cacheNames.getNames());
} else {
cacheManagerSupplier = noOpRecorder.getCacheManagerSupplier(cacheNames.getNames());
cacheManagerSupplier = cacheManagerRecorder.getCacheManagerSupplierWithoutMetrics(cacheNames.getNames());
}

return SyntheticBeanBuildItem.configure(CacheManager.class)
.scope(ApplicationScoped.class)
.supplier(cacheManagerSupplier)
.setRuntimeInit()
.done();
}

private MetricsInitializer getMetricsInitializer(Optional<MetricsCapabilityBuildItem> metricsCapability) {
if (metricsCapability.isPresent() && metricsCapability.get().metricsSupported(MICROMETER)) {
return new MicrometerMetricsInitializer();
}
return new NoOpMetricsInitializer();
}

@BuildStep
List<BytecodeTransformerBuildItem> enhanceRestClientMethods(CombinedIndexBuildItem combinedIndex,
BuildProducer<UnremovableBeanBuildItem> unremovableBeans) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package io.quarkus.cache.deployment;
package io.quarkus.cache.runtime;

import static io.quarkus.runtime.annotations.ConfigPhase.RUN_TIME;

import java.time.Duration;
import java.util.Map;
Expand All @@ -11,9 +13,11 @@
import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigRoot;

@ConfigRoot
@ConfigRoot(phase = RUN_TIME)
public class CacheConfig {

public static final String CAFFEINE_CACHE_TYPE = "caffeine";

/**
* Whether or not the cache extension is enabled.
*/
Expand All @@ -23,13 +27,14 @@ public class CacheConfig {
/**
* Cache type.
*/
@ConfigItem(defaultValue = CacheDeploymentConstants.CAFFEINE_CACHE_TYPE)
String type;
@ConfigItem(defaultValue = CAFFEINE_CACHE_TYPE)
public String type;

/**
* Caffeine configuration.
*/
CaffeineConfig caffeine;
@ConfigItem
public CaffeineConfig caffeine;

@ConfigGroup
public static class CaffeineConfig {
Expand All @@ -39,7 +44,7 @@ public static class CaffeineConfig {
*/
@ConfigItem(name = ConfigItem.PARENT)
@ConfigDocMapKey("cache-name")
Map<String, CaffeineNamespaceConfig> namespace;
public Map<String, CaffeineNamespaceConfig> namespace;

@ConfigGroup
public static class CaffeineNamespaceConfig {
Expand All @@ -49,7 +54,7 @@ public static class CaffeineNamespaceConfig {
* avoids the need for expensive resizing operations later, but setting this value unnecessarily high wastes memory.
*/
@ConfigItem
OptionalInt initialCapacity;
public OptionalInt initialCapacity;

/**
* Maximum number of entries the cache may contain. Note that the cache <b>may evict an entry before this limit is
Expand All @@ -58,27 +63,28 @@ public static class CaffeineNamespaceConfig {
* it hasn't been used recently or very often.
*/
@ConfigItem
OptionalLong maximumSize;
public OptionalLong maximumSize;

/**
* Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after
* the entry's creation, or the most recent replacement of its value.
*/
@ConfigItem
Optional<Duration> expireAfterWrite;
public Optional<Duration> expireAfterWrite;

/**
* Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after
* the entry's creation, the most recent replacement of its value, or its last read.
*/
@ConfigItem
Optional<Duration> expireAfterAccess;
public Optional<Duration> expireAfterAccess;

/**
* Whether or not metrics are recorded if the application depends on the Micrometer extension. Setting this
* value to {@code true} will enable the accumulation of cache stats inside Caffeine.
*/
boolean metricsEnabled;
@ConfigItem
public boolean metricsEnabled;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package io.quarkus.cache.runtime;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;

import io.quarkus.cache.CacheManager;
import io.quarkus.runtime.StartupEvent;

/**
* This class is used to eagerly create the {@link CacheManager} bean instance at STATIC_INIT execution time.
* This class is used to eagerly create the {@link CacheManager} bean instance at RUNTIME_INIT execution time.
*/
public class CacheManagerInitializer {

private static void onStaticInit(@Observes @Initialized(ApplicationScoped.class) Object event, CacheManager cacheManager) {
private static void onStartup(@Observes StartupEvent event, CacheManager cacheManager) {
cacheManager.getCacheNames();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.quarkus.cache.runtime;

import static io.quarkus.cache.runtime.CacheConfig.CAFFEINE_CACHE_TYPE;

import java.util.Set;
import java.util.function.Supplier;

import javax.enterprise.inject.spi.DeploymentException;

import io.quarkus.cache.CacheManager;
import io.quarkus.cache.runtime.caffeine.CaffeineCacheManagerBuilder;
import io.quarkus.cache.runtime.noop.NoOpCacheManagerBuilder;
import io.quarkus.runtime.annotations.Recorder;

@Recorder
public class CacheManagerRecorder {

private final CacheConfig cacheConfig;

public CacheManagerRecorder(CacheConfig cacheConfig) {
this.cacheConfig = cacheConfig;
}

public Supplier<CacheManager> getCacheManagerSupplierWithMicrometerMetrics(Set<String> cacheNames) {
Supplier<Supplier<CacheManager>> caffeineCacheManagerSupplier = new Supplier<Supplier<CacheManager>>() {
@Override
public Supplier<CacheManager> get() {
return CaffeineCacheManagerBuilder.buildWithMicrometerMetrics(cacheNames, cacheConfig);
}
};
return getCacheManagerSupplier(cacheNames, caffeineCacheManagerSupplier);
}

public Supplier<CacheManager> getCacheManagerSupplierWithoutMetrics(Set<String> cacheNames) {
Supplier<Supplier<CacheManager>> caffeineCacheManagerSupplier = new Supplier<Supplier<CacheManager>>() {
@Override
public Supplier<CacheManager> get() {
return CaffeineCacheManagerBuilder.buildWithoutMetrics(cacheNames, cacheConfig);
}
};
return getCacheManagerSupplier(cacheNames, caffeineCacheManagerSupplier);
}

private Supplier<CacheManager> getCacheManagerSupplier(Set<String> cacheNames,
Supplier<Supplier<CacheManager>> caffeineCacheManagerSupplier) {
if (cacheConfig.enabled) {
switch (cacheConfig.type) {
case CAFFEINE_CACHE_TYPE:
return caffeineCacheManagerSupplier.get();
default:
throw new DeploymentException("Unknown cache type: " + cacheConfig.type);
}
} else {
return NoOpCacheManagerBuilder.build(cacheNames);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.quarkus.cache.deployment;
package io.quarkus.cache.runtime.caffeine;

import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;

import io.quarkus.cache.deployment.CacheConfig.CaffeineConfig.CaffeineNamespaceConfig;
import io.quarkus.cache.runtime.caffeine.CaffeineCacheInfo;
import io.quarkus.cache.runtime.CacheConfig;
import io.quarkus.cache.runtime.CacheConfig.CaffeineConfig.CaffeineNamespaceConfig;

public class CaffeineCacheInfoBuilder {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,34 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Supplier;

import org.jboss.logging.Logger;

import io.quarkus.cache.Cache;
import io.quarkus.cache.CacheManager;
import io.quarkus.cache.runtime.CacheConfig;
import io.quarkus.cache.runtime.CacheManagerImpl;
import io.quarkus.cache.runtime.caffeine.metrics.MetricsInitializer;
import io.quarkus.runtime.annotations.Recorder;
import io.quarkus.cache.runtime.caffeine.metrics.MicrometerMetricsInitializer;
import io.quarkus.cache.runtime.caffeine.metrics.NoOpMetricsInitializer;

@Recorder
public class CaffeineCacheBuildRecorder {
public class CaffeineCacheManagerBuilder {

private static final Logger LOGGER = Logger.getLogger(CaffeineCacheBuildRecorder.class);
private static final Logger LOGGER = Logger.getLogger(CaffeineCacheManagerBuilder.class);

public Supplier<CacheManager> getCacheManagerSupplier(Set<CaffeineCacheInfo> cacheInfos,
public static Supplier<CacheManager> buildWithMicrometerMetrics(Set<String> cacheNames, CacheConfig cacheConfig) {
return build(cacheNames, cacheConfig, new MicrometerMetricsInitializer());
}

public static Supplier<CacheManager> buildWithoutMetrics(Set<String> cacheNames, CacheConfig cacheConfig) {
return build(cacheNames, cacheConfig, new NoOpMetricsInitializer());
}

private static Supplier<CacheManager> build(Set<String> cacheNames, CacheConfig cacheConfig,
MetricsInitializer metricsInitializer) {
Objects.requireNonNull(cacheInfos);
Set<CaffeineCacheInfo> cacheInfos = CaffeineCacheInfoBuilder.build(cacheNames, cacheConfig);
return new Supplier<CacheManager>() {
@Override
public CacheManager get() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@
import io.quarkus.cache.Cache;
import io.quarkus.cache.CacheManager;
import io.quarkus.cache.runtime.CacheManagerImpl;
import io.quarkus.runtime.annotations.Recorder;

@Recorder
public class NoOpCacheBuildRecorder {
public class NoOpCacheManagerBuilder {

public Supplier<CacheManager> getCacheManagerSupplier(Set<String> cacheNames) {
public static Supplier<CacheManager> build(Set<String> cacheNames) {
Objects.requireNonNull(cacheNames);
return new Supplier<CacheManager>() {
@Override
Expand Down

0 comments on commit e579cd2

Please sign in to comment.