Skip to content

Commit

Permalink
Add support for puggable backend in quarkus-cache
Browse files Browse the repository at this point in the history
  • Loading branch information
geoand authored and cescoffier committed Mar 15, 2023
1 parent d40800d commit c3a832d
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 93 deletions.
5 changes: 5 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2803,6 +2803,11 @@
<artifactId>quarkus-cache-deployment-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-cache-runtime-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-google-cloud-functions</artifactId>
Expand Down
4 changes: 4 additions & 0 deletions extensions/cache/deployment-spi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-cache-runtime-spi</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.quarkus.cache.deployment.spi;

import io.quarkus.builder.item.MultiBuildItem;
import io.quarkus.cache.CacheManagerInfo;

/**
* TODO: add
*/
public final class CacheManagerInfoBuildItem extends MultiBuildItem {

private final CacheManagerInfo info;

public CacheManagerInfoBuildItem(CacheManagerInfo info) {
this.info = info;
}

public CacheManagerInfo get() {
return info;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import io.quarkus.cache.deployment.exception.UnsupportedRepeatedAnnotationException;
import io.quarkus.cache.deployment.exception.VoidReturnTypeTargetException;
import io.quarkus.cache.deployment.spi.AdditionalCacheNameBuildItem;
import io.quarkus.cache.deployment.spi.CacheManagerInfoBuildItem;
import io.quarkus.cache.runtime.CacheInvalidateAllInterceptor;
import io.quarkus.cache.runtime.CacheInvalidateInterceptor;
import io.quarkus.cache.runtime.CacheManagerRecorder;
Expand Down Expand Up @@ -232,17 +233,26 @@ private List<Throwable> validateKeyGeneratorsDefaultConstructor(CombinedIndexBui

@BuildStep
@Record(RUNTIME_INIT)
SyntheticBeanBuildItem configureCacheManagerSyntheticBean(CacheNamesBuildItem cacheNames,
CacheManagerRecorder cacheManagerRecorder, Optional<MetricsCapabilityBuildItem> metricsCapability) {
void cacheManagerInfos(BuildProducer<CacheManagerInfoBuildItem> producer,
Optional<MetricsCapabilityBuildItem> metricsCapability, CacheManagerRecorder recorder) {
producer.produce(new CacheManagerInfoBuildItem(recorder.noOpCacheManagerInfo()));
producer.produce(new CacheManagerInfoBuildItem(recorder.getCacheManagerInfoWithoutMetrics()));
if (metricsCapability.isPresent() && metricsCapability.get().metricsSupported(MICROMETER)) {
// if we include this unconditionally the native image building will fail when Micrometer is not around
producer.produce(new CacheManagerInfoBuildItem(recorder.getCacheManagerInfoWithMicrometerMetrics()));
}
}

boolean micrometerSupported = metricsCapability.isPresent() && metricsCapability.get().metricsSupported(MICROMETER);
@BuildStep
@Record(RUNTIME_INIT)
SyntheticBeanBuildItem configureCacheManagerSyntheticBean(List<CacheManagerInfoBuildItem> infos,
CacheNamesBuildItem cacheNames, Optional<MetricsCapabilityBuildItem> metricsCapability,
CacheManagerRecorder cacheManagerRecorder) {

Supplier<CacheManager> cacheManagerSupplier;
if (micrometerSupported) {
cacheManagerSupplier = cacheManagerRecorder.getCacheManagerSupplierWithMicrometerMetrics(cacheNames.getNames());
} else {
cacheManagerSupplier = cacheManagerRecorder.getCacheManagerSupplierWithoutMetrics(cacheNames.getNames());
}
boolean micrometerSupported = metricsCapability.isPresent() && metricsCapability.get().metricsSupported(MICROMETER);
Supplier<CacheManager> cacheManagerSupplier = cacheManagerRecorder.resolveCacheInfo(
infos.stream().map(CacheManagerInfoBuildItem::get).collect(toList()), cacheNames.getNames(),
micrometerSupported);

return SyntheticBeanBuildItem.configure(CacheManager.class)
.scope(ApplicationScoped.class)
Expand Down
1 change: 1 addition & 0 deletions extensions/cache/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
<module>deployment</module>
<module>deployment-spi</module>
<module>runtime</module>
<module>runtime-spi</module>
</modules>
</project>
40 changes: 40 additions & 0 deletions extensions/cache/runtime-spi/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-cache-parent</artifactId>
<version>999-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-cache-runtime-spi</artifactId>
<name>Quarkus - Cache - Runtime SPI</name>

<dependencies>
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>mutiny</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>


</project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

/**
* Use this interface to interact with a cache programmatically e.g. store, retrieve or delete cache values. The cache can be
* injected using the {@link CacheName} annotation or retrieved using {@link CacheManager#getCache(String)}.
* injected using the {@code @io.quarkus.cache.CacheName} annotation or retrieved using {@link CacheManager#getCache(String)}.
*/
public interface Cache {

Expand All @@ -20,7 +20,8 @@ public interface Cache {

/**
* Returns the unique and immutable default key for the current cache. This key is used by the annotations caching API when
* a no-args method annotated with {@link CacheResult} or {@link CacheInvalidate} is invoked. It can also be used with the
* a no-args method annotated with {@code @io.quarkus.cache.CacheResult} or {@code @io.quarkus.cache.CacheInvalidate} is
* invoked. It can also be used with the
* programmatic caching API.
*
* @return default cache key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* <p>
* Use this interface to retrieve all existing {@link Cache} names and interact with any cache programmatically e.g. store,
* retrieve or delete cache values. It shares the same caches collection the Quarkus caching annotations use. The
* {@link CacheName} annotation can also be used to inject and access a specific cache from its name.
* {@code @io.quarkus.cache.CacheName} annotation can also be used to inject and access a specific cache from its name.
* </p>
* <p>
* Code example:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.quarkus.cache;

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

public interface CacheManagerInfo {

boolean supports(Context context);

Supplier<CacheManager> get(Context context);

interface Context {

boolean cacheEnabled();

Metrics metrics();

String cacheType();

Set<String> cacheNames();

enum Metrics {
NONE,
MICROMETER
}
}
}
4 changes: 4 additions & 0 deletions extensions/cache/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mutiny</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-cache-runtime-spi</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.quarkus.cache.runtime;

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

import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;

@ConfigRoot(phase = BUILD_AND_RUN_TIME_FIXED)
@ConfigMapping(prefix = "quarkus.cache")
public interface CacheBuildConfig {

String CAFFEINE_CACHE_TYPE = "caffeine";

/**
* Cache type.
*/
@WithDefault(CAFFEINE_CACHE_TYPE)
String type();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,90 +10,76 @@

import io.quarkus.runtime.annotations.ConfigDocMapKey;
import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import io.smallrye.config.WithParentName;

@ConfigRoot(phase = RUN_TIME)
public class CacheConfig {

public static final String CAFFEINE_CACHE_TYPE = "caffeine";
@ConfigMapping(prefix = "quarkus.cache")
public interface CacheConfig {

/**
* Whether or not the cache extension is enabled.
*/
@ConfigItem(defaultValue = "true")
public boolean enabled;

/**
* Cache type.
*/
@ConfigItem(defaultValue = CAFFEINE_CACHE_TYPE)
public String type;
@WithDefault("true")
boolean enabled();

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

@ConfigGroup
public static class CaffeineConfig {
interface CaffeineConfig {

/**
* Default configuration applied to all Caffeine caches (lowest precedence)
*/
@ConfigItem(name = ConfigItem.PARENT)
@WithParentName
@ConfigDocSection
public CaffeineCacheConfig defaultConfig;
CaffeineCacheConfig defaultConfig();

/**
* Additional configuration applied to a specific Caffeine cache (highest precedence)
*/
@ConfigItem(name = ConfigItem.PARENT)
@WithParentName
@ConfigDocMapKey("cache-name")
@ConfigDocSection
public Map<String, CaffeineCacheConfig> cachesConfig;
Map<String, CaffeineCacheConfig> cachesConfig();

@ConfigGroup
public static class CaffeineCacheConfig {
interface CaffeineCacheConfig {

/**
* Minimum total size for the internal data structures. Providing a large enough estimate at construction time
* avoids the need for expensive resizing operations later, but setting this value unnecessarily high wastes memory.
*/
@ConfigItem
public OptionalInt initialCapacity;
OptionalInt initialCapacity();

/**
* Maximum number of entries the cache may contain. Note that the cache <b>may evict an entry before this limit is
* exceeded or temporarily exceed the threshold while evicting</b>. As the cache size grows close to the maximum,
* the cache evicts entries that are less likely to be used again. For example, the cache may evict an entry because
* it hasn't been used recently or very often.
*/
@ConfigItem
public OptionalLong maximumSize;
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
public Optional<Duration> expireAfterWrite;
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
public Optional<Duration> expireAfterAccess;
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.
*/
@ConfigItem
public Optional<Boolean> metricsEnabled;
Optional<Boolean> metricsEnabled();
}
}
}
Loading

0 comments on commit c3a832d

Please sign in to comment.