Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Qute + Cache integration #35817

Merged
merged 3 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.quarkus.cache.deployment.spi;

import io.quarkus.builder.item.SimpleBuildItem;

/**
* A build item that can be used by extensions to determine what kind of cache backend is configured.
* This is useful for cases where caching extensions specific data does not make sense for remote cache backends
*/
public final class CacheTypeBuildItem extends SimpleBuildItem {

private final Type type;

public CacheTypeBuildItem(Type type) {
this.type = type;
}

public Type getType() {
return type;
}

public enum Type {
LOCAL,
REMOTE
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +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.cache.runtime.CacheBuildConfig.CAFFEINE_CACHE_TYPE;
import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT;
import static io.quarkus.runtime.metrics.MetricsFactory.MICROMETER;
import static java.util.stream.Collectors.toList;
Expand Down Expand Up @@ -54,6 +55,8 @@
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.deployment.spi.CacheTypeBuildItem;
import io.quarkus.cache.runtime.CacheBuildConfig;
import io.quarkus.cache.runtime.CacheInvalidateAllInterceptor;
import io.quarkus.cache.runtime.CacheInvalidateInterceptor;
import io.quarkus.cache.runtime.CacheManagerRecorder;
Expand Down Expand Up @@ -92,6 +95,12 @@ RestClientAnnotationsTransformerBuildItem restClientAnnotationsTransformer() {
return new RestClientAnnotationsTransformerBuildItem(new RestClientCacheAnnotationsTransformer());
}

@BuildStep
CacheTypeBuildItem type(CacheBuildConfig config) {
return new CacheTypeBuildItem(
CAFFEINE_CACHE_TYPE.equals(config.type()) ? CacheTypeBuildItem.Type.LOCAL : CacheTypeBuildItem.Type.REMOTE);
}

@BuildStep
void validateCacheAnnotationsAndProduceCacheNames(CombinedIndexBuildItem combinedIndex,
List<AdditionalCacheNameBuildItem> additionalCacheNames,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
package io.quarkus.qute.deployment;

import java.util.Optional;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.cache.deployment.spi.AdditionalCacheNameBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.cache.deployment.spi.CacheTypeBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.qute.cache.QuteCache;
import io.quarkus.qute.runtime.cache.CacheConfigurator;
import io.quarkus.qute.runtime.cache.MissingCacheConfigurator;
import io.quarkus.qute.runtime.cache.UnsupportedRemoteCacheConfigurator;

public class CacheProcessor {

@BuildStep
void initialize(Capabilities capabilities, BuildProducer<AdditionalBeanBuildItem> beans,
void initialize(Optional<CacheTypeBuildItem> cacheTypeBuildItem,
BuildProducer<AdditionalBeanBuildItem> beans,
BuildProducer<AdditionalCacheNameBuildItem> cacheNames) {
if (capabilities.isPresent(Capability.CACHE)) {
beans.produce(new AdditionalBeanBuildItem("io.quarkus.qute.runtime.cache.CacheConfigurator"));
// We need to produce additional cache name because quarkus-cache only considers the CombinedIndexBuildItem and not the bean archive index
Class configuratorClass;
boolean supported = false;
if (cacheTypeBuildItem.isEmpty()) { // no caching enabled
configuratorClass = MissingCacheConfigurator.class;
} else {
CacheTypeBuildItem.Type type = cacheTypeBuildItem.get().getType();
if (type != CacheTypeBuildItem.Type.LOCAL) { // it does not make sense to use a remote cache for Qute
configuratorClass = UnsupportedRemoteCacheConfigurator.class;
} else {
configuratorClass = CacheConfigurator.class;
supported = true;
}
}

beans.produce(new AdditionalBeanBuildItem(configuratorClass.getName()));
// We need to produce additional cache name because quarkus-cache only considers the CombinedIndexBuildItem and not the bean archive index
if (supported) {
cacheNames.produce(new AdditionalCacheNameBuildItem(QuteCache.NAME));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.qute.runtime.cache;

import java.util.concurrent.CompletionStage;
import java.util.function.Function;

import jakarta.enterprise.event.Observes;

import io.quarkus.qute.CacheSectionHelper;
import io.quarkus.qute.EngineBuilder;
import io.quarkus.qute.ResultNode;

public class MissingCacheConfigurator {

void configureEngine(@Observes EngineBuilder builder) {
builder.addSectionHelper(new CacheSectionHelper.Factory(new CacheSectionHelper.Cache() {

@Override
public CompletionStage<ResultNode> getValue(String key, Function<String, CompletionStage<ResultNode>> loader) {
throw new IllegalStateException("#cache cannot be used without the 'quarkus-cache' extension");
}
}));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.qute.runtime.cache;

import java.util.concurrent.CompletionStage;
import java.util.function.Function;

import jakarta.enterprise.event.Observes;

import io.quarkus.qute.CacheSectionHelper;
import io.quarkus.qute.EngineBuilder;
import io.quarkus.qute.ResultNode;

public class UnsupportedRemoteCacheConfigurator {

void configureEngine(@Observes EngineBuilder builder) {
builder.addSectionHelper(new CacheSectionHelper.Factory(new CacheSectionHelper.Cache() {

@Override
public CompletionStage<ResultNode> getValue(String key, Function<String, CompletionStage<ResultNode>> loader) {
throw new IllegalStateException("#cache is not supported for remote caches");
}
}));
}

}