aboutsummaryrefslogtreecommitdiffstats
path: root/container-core/src/main/java/com/yahoo/container/di/ConfigRetriever.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-core/src/main/java/com/yahoo/container/di/ConfigRetriever.java')
-rw-r--r--container-core/src/main/java/com/yahoo/container/di/ConfigRetriever.java87
1 files changed, 45 insertions, 42 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/di/ConfigRetriever.java b/container-core/src/main/java/com/yahoo/container/di/ConfigRetriever.java
index ff238bd2497..1e7f3e06049 100644
--- a/container-core/src/main/java/com/yahoo/container/di/ConfigRetriever.java
+++ b/container-core/src/main/java/com/yahoo/container/di/ConfigRetriever.java
@@ -5,9 +5,9 @@ import com.google.common.collect.Sets;
import com.yahoo.config.ConfigInstance;
import com.yahoo.container.di.componentgraph.core.Keys;
import com.yahoo.container.di.config.Subscriber;
-import com.yahoo.container.di.config.SubscriberFactory;
import com.yahoo.vespa.config.ConfigKey;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
@@ -29,21 +29,20 @@ public final class ConfigRetriever {
private final Set<ConfigKey<? extends ConfigInstance>> bootstrapKeys;
private Set<ConfigKey<? extends ConfigInstance>> componentSubscriberKeys;
-
- private final SubscriberFactory subscriberFactory;
private final Subscriber bootstrapSubscriber;
private Subscriber componentSubscriber;
- private int componentSubscriberIndex;
+ private final Function<Set<ConfigKey<? extends ConfigInstance>>, Subscriber> subscribe;
- public ConfigRetriever(Set<ConfigKey<? extends ConfigInstance>> bootstrapKeys, SubscriberFactory subscriberFactory) {
+ public ConfigRetriever(Set<ConfigKey<? extends ConfigInstance>> bootstrapKeys,
+ Function<Set<ConfigKey<? extends ConfigInstance>>, Subscriber> subscribe) {
this.bootstrapKeys = bootstrapKeys;
this.componentSubscriberKeys = new HashSet<>();
- this.subscriberFactory = subscriberFactory;
+ this.subscribe = subscribe;
if (bootstrapKeys.isEmpty()) {
throw new IllegalArgumentException("Bootstrap key set is empty");
}
- this.bootstrapSubscriber = this.subscriberFactory.getSubscriber(bootstrapKeys, "bootstrap");
- this.componentSubscriber = this.subscriberFactory.getSubscriber(componentSubscriberKeys, "component_" + ++componentSubscriberIndex);
+ this.bootstrapSubscriber = subscribe.apply(bootstrapKeys);
+ this.componentSubscriber = subscribe.apply(componentSubscriberKeys);
}
public ConfigSnapshot getConfigs(Set<ConfigKey<? extends ConfigInstance>> componentConfigKeys,
@@ -52,56 +51,55 @@ public final class ConfigRetriever {
while (true) {
Optional<ConfigSnapshot> maybeSnapshot = getConfigsOnce(componentConfigKeys, leastGeneration, isInitializing);
if (maybeSnapshot.isPresent()) {
- return maybeSnapshot.get();
+ var configSnapshot = maybeSnapshot.get();
+ resetComponentSubscriberIfBootstrap(configSnapshot);
+ return configSnapshot;
}
}
}
- private Optional<ConfigSnapshot> getConfigsOnce(Set<ConfigKey<? extends ConfigInstance>> componentConfigKeys,
- long leastGeneration, boolean isInitializing) {
+ Optional<ConfigSnapshot> getConfigsOnce(Set<ConfigKey<? extends ConfigInstance>> componentConfigKeys,
+ long leastGeneration, boolean isInitializing) {
if (!Sets.intersection(componentConfigKeys, bootstrapKeys).isEmpty()) {
throw new IllegalArgumentException(
"Component config keys [" + componentConfigKeys + "] overlaps with bootstrap config keys [" + bootstrapKeys + "]");
}
+ log.log(FINE, () -> "getConfigsOnce: " + componentConfigKeys);
+
Set<ConfigKey<? extends ConfigInstance>> allKeys = new HashSet<>(componentConfigKeys);
allKeys.addAll(bootstrapKeys);
setupComponentSubscriber(allKeys);
- var maybeSnapshot = getConfigsOptional(leastGeneration, isInitializing);
- log.log(FINE, () -> "getConfigsOnce returning " + maybeSnapshot);
- return maybeSnapshot;
+ return getConfigsOptional(leastGeneration, isInitializing);
}
private Optional<ConfigSnapshot> getConfigsOptional(long leastGeneration, boolean isInitializing) {
- if (componentSubscriber.generation() < bootstrapSubscriber.generation()) {
- return getComponentsSnapshot(leastGeneration, isInitializing);
- }
- long newestBootstrapGeneration = bootstrapSubscriber.waitNextGeneration(isInitializing);
- log.log(FINE, () -> "getConfigsOptional: new bootstrap generation: " + newestBootstrapGeneration);
-
- // leastGeneration is used to ensure newer generation (than the latest bootstrap or component gen)
- // when the previous generation was invalidated due to an exception upon creating the component graph.
- if (newestBootstrapGeneration < leastGeneration) {
- return Optional.empty();
- }
- return bootstrapConfigIfChanged();
- }
-
- private Optional<ConfigSnapshot> getComponentsSnapshot(long leastGeneration, boolean isInitializing) {
- long newestBootstrapGeneration = bootstrapSubscriber.generation();
long newestComponentGeneration = componentSubscriber.waitNextGeneration(isInitializing);
+ log.log(FINE, () -> "getConfigsOptional: new component generation: " + newestComponentGeneration);
+
+ // leastGeneration is only used to ensure newer generation when the previous generation was invalidated due to an exception
if (newestComponentGeneration < leastGeneration) {
- log.log(FINE, () -> "Component generation too old: " + componentSubscriber.generation() + " < " + leastGeneration);
return Optional.empty();
- }
- if (newestComponentGeneration == newestBootstrapGeneration) {
- log.log(FINE, () -> "getConfigsOptional: new component generation: " + componentSubscriber.generation());
- return componentsConfigIfChanged();
- } else {
- // Should not be a normal case, and hence a warning to allow investigation.
- log.warning("Did not get same generation for bootstrap (" + newestBootstrapGeneration +
+ } else if (bootstrapSubscriber.generation() < newestComponentGeneration) {
+ long newestBootstrapGeneration = bootstrapSubscriber.waitNextGeneration(isInitializing);
+ log.log(FINE, () -> "getConfigsOptional: new bootstrap generation: " + bootstrapSubscriber.generation());
+ Optional<ConfigSnapshot> bootstrapConfig = bootstrapConfigIfChanged();
+ if (bootstrapConfig.isPresent()) {
+ return bootstrapConfig;
+ } else {
+ if (newestBootstrapGeneration == newestComponentGeneration) {
+ log.log(FINE, () -> "Got new components configs with unchanged bootstrap configs.");
+ return componentsConfigIfChanged();
+ } else {
+ // This should not be a normal case, and hence a warning to allow investigation.
+ log.warning("Did not get same generation for bootstrap (" + newestBootstrapGeneration +
") and components configs (" + newestComponentGeneration + ").");
- return Optional.empty();
+ return Optional.empty();
+ }
+ }
+ } else {
+ // bootstrapGen==componentGen (happens only when a new component subscriber returns first config after bootstrap)
+ return componentsConfigIfChanged();
}
}
@@ -122,14 +120,19 @@ public final class ConfigRetriever {
}
}
+ private void resetComponentSubscriberIfBootstrap(ConfigSnapshot snapshot) {
+ if (snapshot instanceof BootstrapConfigs) {
+ setupComponentSubscriber(Collections.emptySet());
+ }
+ }
+
private void setupComponentSubscriber(Set<ConfigKey<? extends ConfigInstance>> keys) {
if (! componentSubscriberKeys.equals(keys)) {
componentSubscriber.close();
- log.log(FINE, () -> "Closed " + componentSubscriber);
componentSubscriberKeys = keys;
try {
- componentSubscriber = subscriberFactory.getSubscriber(keys, "component_" + ++componentSubscriberIndex);
- log.log(FINE, () -> "Set up new subscriber " + componentSubscriber + " for keys: " + keys);
+ log.log(FINE, () -> "Setting up new component subscriber for keys: " + keys);
+ componentSubscriber = subscribe.apply(keys);
} catch (Throwable e) {
log.log(Level.WARNING, "Failed setting up subscriptions for component configs: " + e.getMessage());
log.log(Level.WARNING, "Config keys: " + keys);