From 7222bb83f5576af5592164f15093533bbe657fc9 Mon Sep 17 00:00:00 2001 From: Alexey Loubyansky Date: Mon, 4 Nov 2019 19:01:11 +0100 Subject: [PATCH] Use ThreadLocal to store the global value only for gradle add and list extensions tasks, otherwise the default global config should use a static field --- .../gradle/tasks/QuarkusAddExtension.java | 5 +- .../gradle/tasks/QuarkusListExtensions.java | 6 +- .../gradle/tasks/QuarkusPlatformTask.java | 20 ++++- .../tools/config/QuarkusPlatformConfig.java | 75 +++++++++++++++---- 4 files changed, 85 insertions(+), 21 deletions(-) diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusAddExtension.java b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusAddExtension.java index 9639f52cc..c820723b5 100644 --- a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusAddExtension.java +++ b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusAddExtension.java @@ -39,8 +39,11 @@ public class QuarkusAddExtension extends QuarkusPlatformTask { @TaskAction public void addExtension() { - setupPlatformDescriptor(); + execute(); + } + @Override + protected void doExecute() { Set extensionsSet = getExtensionsToAdd() .stream() .flatMap(ext -> stream(ext.split(","))) diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusListExtensions.java b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusListExtensions.java index f845003c5..3850f4797 100644 --- a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusListExtensions.java +++ b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusListExtensions.java @@ -62,9 +62,11 @@ public class QuarkusListExtensions extends QuarkusPlatformTask { @TaskAction public void listExtensions() { + execute(); + } - setupPlatformDescriptor(); - + @Override + protected void doExecute() { try { new ListExtensions(new GradleBuildFileFromConnector(new FileProjectWriter(getProject().getProjectDir()))) .listExtensions( diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java index 810f640a6..324149d43 100644 --- a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java +++ b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java @@ -10,16 +10,30 @@ import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor; import io.quarkus.platform.descriptor.resolver.json.QuarkusJsonPlatformDescriptorResolver; import io.quarkus.platform.tools.config.QuarkusPlatformConfig; -public class QuarkusPlatformTask extends QuarkusTask { +public abstract class QuarkusPlatformTask extends QuarkusTask { QuarkusPlatformTask(String description) { super(description); } + protected void execute() { + try { + setupPlatformDescriptor(); + doExecute(); + } finally { + QuarkusPlatformConfig.clearThreadLocal(); + } + } + + protected abstract void doExecute(); + protected void setupPlatformDescriptor() { - if (QuarkusPlatformConfig.hasGlobalDefault()) { + if (QuarkusPlatformConfig.hasThreadLocal()) { + getProject().getLogger().debug("Quarkus platform descriptor has already been initialized"); return; + } else { + getProject().getLogger().debug("Initializing Quarkus platform descriptor"); } final Path currentDir = getProject().getProjectDir().toPath(); @@ -41,7 +55,7 @@ public class QuarkusPlatformTask extends QuarkusTask { getRequiredProperty(props, "quarkusPlatformArtifactId"), getRequiredProperty(props, "quarkusPlatformVersion")); - QuarkusPlatformConfig.defaultConfigBuilder().setPlatformDescriptor(platform).build(); + QuarkusPlatformConfig.threadLocalConfigBuilder().setPlatformDescriptor(platform).build(); } else { getProject().getLogger() diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/platform/tools/config/QuarkusPlatformConfig.java b/independent-projects/tools/common/src/main/java/io/quarkus/platform/tools/config/QuarkusPlatformConfig.java index 2a7cee114..3b87e6503 100644 --- a/independent-projects/tools/common/src/main/java/io/quarkus/platform/tools/config/QuarkusPlatformConfig.java +++ b/independent-projects/tools/common/src/main/java/io/quarkus/platform/tools/config/QuarkusPlatformConfig.java @@ -2,6 +2,8 @@ package io.quarkus.platform.tools.config; import java.util.Iterator; import java.util.ServiceLoader; +import java.util.concurrent.atomic.AtomicReference; + import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor; import io.quarkus.platform.descriptor.loader.QuarkusPlatformDescriptorLoader; import io.quarkus.platform.descriptor.loader.QuarkusPlatformDescriptorLoaderContext; @@ -12,14 +14,17 @@ public class QuarkusPlatformConfig { public static class Builder { - private boolean buildDefaultConfig; + private int type = STANDALONE; private MessageWriter log; private QuarkusPlatformDescriptor platformDescr; - private Builder(boolean buildSingleton) { - if (this.buildDefaultConfig = buildSingleton) { - assertNoDefaultConfig(); + private Builder(int type) { + if(type == GLOBAL) { + assertNoGlobalConfig(); + } else if(type == THREAD_LOCAL) { + assertNoThreadLocalConfig(); } + this.type = type; } public Builder setMessageWriter(MessageWriter msgWriter) { @@ -68,7 +73,7 @@ public class QuarkusPlatformConfig { } public static Builder builder() { - return new Builder(false); + return new Builder(STANDALONE); } /** @@ -77,7 +82,16 @@ public class QuarkusPlatformConfig { * as the global default config. */ public static Builder defaultConfigBuilder() { - return new Builder(true); + return new Builder(GLOBAL); + } + + /** + * This hopefully will be a temporary way of providing global default config + * by creating a builder that will create a config instance which will serve + * as the global default config. + */ + public static Builder threadLocalConfigBuilder() { + return new Builder(THREAD_LOCAL); } public static QuarkusPlatformConfig newInstance() { @@ -85,7 +99,7 @@ public class QuarkusPlatformConfig { } public static QuarkusPlatformConfig getGlobalDefault() { - final QuarkusPlatformConfig c = defaultConfig.get(); + final QuarkusPlatformConfig c = globalConfig.get(); if(c != null) { return c; } @@ -93,17 +107,45 @@ public class QuarkusPlatformConfig { } public static boolean hasGlobalDefault() { - return defaultConfig.get() != null; + return globalConfig.get() != null; } - private static void assertNoDefaultConfig() { - if (defaultConfig.get() != null) { + public static QuarkusPlatformConfig getThreadLocal() { + final QuarkusPlatformConfig c = threadLocalConfig.get(); + if(c != null) { + return c; + } + return threadLocalConfigBuilder().build(); + } + + public static boolean hasThreadLocal() { + return threadLocalConfig.get() != null; + } + + public static void clearThreadLocal() { + threadLocalConfig.remove(); + } + + private static void assertNoGlobalConfig() { + if (globalConfig.get() != null) { throw new IllegalStateException( - "The default instance of " + QuarkusPlatformConfig.class.getName() + " has already been initialized"); + "The global instance of " + QuarkusPlatformConfig.class.getName() + " has already been initialized"); } } - private static final ThreadLocal defaultConfig = new ThreadLocal<>(); + private static void assertNoThreadLocalConfig() { + if (threadLocalConfig.get() != null) { + throw new IllegalStateException( + "The thread local instance of " + QuarkusPlatformConfig.class.getName() + " has already been initialized"); + } + } + + private static final int STANDALONE = 0; + private static final int GLOBAL = 1; + private static final int THREAD_LOCAL = 2; + + private static final AtomicReference globalConfig = new AtomicReference<>(); + private static final ThreadLocal threadLocalConfig = new ThreadLocal<>(); private final MessageWriter log; private final QuarkusPlatformDescriptor platformDescr; @@ -111,9 +153,12 @@ public class QuarkusPlatformConfig { private QuarkusPlatformConfig(Builder builder) { this.log = builder.getMessageWriter(); this.platformDescr = builder.getPlatformDescriptor(); - if(builder.buildDefaultConfig) { - assertNoDefaultConfig(); - defaultConfig.set(this); + if(builder.type == GLOBAL) { + assertNoGlobalConfig(); + globalConfig.set(this); + } else if(builder.type == THREAD_LOCAL) { + assertNoThreadLocalConfig(); + threadLocalConfig.set(this); } }