diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-10-14 18:01:16 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-14 18:01:16 +0200 |
commit | 868c29b272eb7773d5c4515cb33640a44074d05a (patch) | |
tree | 1fdcbfbb9840a92e8068e20296a94c12a5da389f /container-core/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java | |
parent | ffcc28f2b9180ad8774c67fddbebc81b41f2fc6c (diff) |
Revert "Container config improvements [run-systemtest]"
Diffstat (limited to 'container-core/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java')
-rw-r--r-- | container-core/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java | 84 |
1 files changed, 80 insertions, 4 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java b/container-core/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java index a6327b01e21..d50d56f8987 100644 --- a/container-core/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java +++ b/container-core/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java @@ -2,19 +2,24 @@ package com.yahoo.container.di; import com.yahoo.config.ConfigInstance; +import com.yahoo.config.subscription.ConfigHandle; import com.yahoo.config.subscription.ConfigSource; import com.yahoo.config.subscription.ConfigSourceSet; +import com.yahoo.config.subscription.ConfigSubscriber; import com.yahoo.container.di.config.Subscriber; import com.yahoo.container.di.config.SubscriberFactory; import com.yahoo.vespa.config.ConfigKey; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.WeakHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @author Tony Vaagenes @@ -22,6 +27,8 @@ import java.util.WeakHashMap; */ public class CloudSubscriberFactory implements SubscriberFactory { + private static final Logger log = Logger.getLogger(CloudSubscriberFactory.class.getName()); + private final ConfigSource configSource; private final Map<CloudSubscriber, Integer> activeSubscribers = new WeakHashMap<>(); @@ -32,16 +39,16 @@ public class CloudSubscriberFactory implements SubscriberFactory { } @Override - public Subscriber getSubscriber(Set<? extends ConfigKey<?>> configKeys, String name) { + public Subscriber getSubscriber(Set<? extends ConfigKey<?>> configKeys) { Set<ConfigKey<ConfigInstance>> subscriptionKeys = new HashSet<>(); for(ConfigKey<?> key: configKeys) { @SuppressWarnings("unchecked") // ConfigKey is defined as <CONFIGCLASS extends ConfigInstance> ConfigKey<ConfigInstance> invariant = (ConfigKey<ConfigInstance>) key; subscriptionKeys.add(invariant); } - CloudSubscriber subscriber = new CloudSubscriber(name, configSource, subscriptionKeys); + CloudSubscriber subscriber = new CloudSubscriber(subscriptionKeys, configSource); - testGeneration.ifPresent(subscriber.getSubscriber()::reload); // TODO: test specific code, remove + testGeneration.ifPresent(subscriber.subscriber::reload); // TODO: test specific code, remove activeSubscribers.put(subscriber, 0); return subscriber; @@ -53,7 +60,76 @@ public class CloudSubscriberFactory implements SubscriberFactory { testGeneration = Optional.of(generation); List<CloudSubscriber> subscribers = new ArrayList<>(activeSubscribers.keySet()); - subscribers.forEach(s -> s.getSubscriber().reload(generation)); + subscribers.forEach(s -> s.subscriber.reload(generation)); + } + + private static class CloudSubscriber implements Subscriber { + + private final ConfigSubscriber subscriber; + private final Map<ConfigKey<ConfigInstance>, ConfigHandle<ConfigInstance>> handles = new HashMap<>(); + + // if waitNextGeneration has not yet been called, -1 should be returned + private long generation = -1L; + + private CloudSubscriber(Set<ConfigKey<ConfigInstance>> keys, ConfigSource configSource) { + this.subscriber = new ConfigSubscriber(configSource); + keys.forEach(k -> handles.put(k, subscriber.subscribe(k.getConfigClass(), k.getConfigId()))); + } + + @Override + public boolean configChanged() { + return handles.values().stream().anyMatch(ConfigHandle::isChanged); + } + + @Override + public long generation() { + return generation; + } + + //mapValues returns a view,, so we need to force evaluation of it here to prevent deferred evaluation. + @Override + public Map<ConfigKey<ConfigInstance>, ConfigInstance> config() { + Map<ConfigKey<ConfigInstance>, ConfigInstance> ret = new HashMap<>(); + handles.forEach((k, v) -> ret.put(k, v.getConfig())); + return ret; + } + + @Override + public long waitNextGeneration(boolean isInitializing) { + if (handles.isEmpty()) + throw new IllegalStateException("No config keys registered"); + + // Catch and just log config exceptions due to missing config values for parameters that do + // not have a default value. These exceptions occur when the user has removed a component + // from services.xml, and the component takes a config that has parameters without a + // default value in the def-file. There is a new 'components' config underway, where the + // component is removed, so this old config generation will soon be replaced by a new one. + boolean gotNextGen = false; + int numExceptions = 0; + while ( ! gotNextGen) { + try { + if (subscriber.nextGeneration(isInitializing)) + gotNextGen = true; + } + catch (IllegalArgumentException e) { + numExceptions++; + log.log(Level.WARNING, "Got exception from the config system (ignore if you just removed a " + + "component from your application that used the mentioned config) Subscriber info: " + + subscriber.toString(), e); + if (numExceptions >= 5) + throw new IllegalArgumentException("Failed retrieving the next config generation", e); + } + } + + generation = subscriber.getGeneration(); + return generation; + } + + @Override + public void close() { + subscriber.close(); + } + } public static class Provider implements com.google.inject.Provider<SubscriberFactory> { |