diff options
author | Jon Bratseth <bratseth@gmail.com> | 2020-12-16 22:15:52 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2020-12-16 22:15:52 +0100 |
commit | b194c494bc568ced02a98695bc41219b170acf37 (patch) | |
tree | 0e22193a21aeddb945663795232066c44fc2e3eb /config | |
parent | 99ad735154f1aa3cd40b7d7028c11bf19225d1b3 (diff) |
Track explicitly when we are initializing config
Diffstat (limited to 'config')
12 files changed, 66 insertions, 37 deletions
diff --git a/config/abi-spec.json b/config/abi-spec.json index a41df9aa60d..fa016fd91da 100644 --- a/config/abi-spec.json +++ b/config/abi-spec.json @@ -202,9 +202,13 @@ "public com.yahoo.config.subscription.ConfigHandle subscribe(java.lang.Class, java.lang.String, long)", "protected void checkStateBeforeSubscribe()", "protected void subscribeAndHandleErrors(com.yahoo.config.subscription.impl.ConfigSubscription, com.yahoo.vespa.config.ConfigKey, com.yahoo.config.subscription.ConfigHandle, com.yahoo.vespa.config.TimingValues)", + "public boolean nextConfig(boolean)", "public boolean nextConfig()", + "public boolean nextConfig(long, boolean)", "public boolean nextConfig(long)", + "public boolean nextGeneration(boolean)", "public boolean nextGeneration()", + "public boolean nextGeneration(long, boolean)", "public boolean nextGeneration(long)", "protected void throwIfExceptionSet(com.yahoo.config.subscription.impl.ConfigSubscription)", "public void close()", diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigGetter.java b/config/src/main/java/com/yahoo/config/subscription/ConfigGetter.java index b2aa0147259..e3d1f2eac55 100755 --- a/config/src/main/java/com/yahoo/config/subscription/ConfigGetter.java +++ b/config/src/main/java/com/yahoo/config/subscription/ConfigGetter.java @@ -50,7 +50,7 @@ public class ConfigGetter<T extends ConfigInstance> { try (ConfigSubscriber subscriber = source == null ? new ConfigSubscriber() : new ConfigSubscriber(source)) { ConfigHandle<T> handle = subscriber.subscribe(clazz, configId); - subscriber.nextConfig(); + subscriber.nextConfig(true); return handle.getConfig(); } } diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigHandle.java b/config/src/main/java/com/yahoo/config/subscription/ConfigHandle.java index c0eb3e98157..6a271f6a401 100644 --- a/config/src/main/java/com/yahoo/config/subscription/ConfigHandle.java +++ b/config/src/main/java/com/yahoo/config/subscription/ConfigHandle.java @@ -1,7 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription; - import com.yahoo.config.ConfigInstance; import com.yahoo.config.subscription.impl.ConfigSubscription; @@ -23,7 +22,6 @@ public class ConfigHandle<T extends ConfigInstance> { /** * Returns true if: - * * The config generation for the {@link ConfigSubscriber} that produced this is the first one in its life cycle. (Typically first time config.) * or * All configs for the subscriber have a new generation since the last time nextConfig() was called diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java index 57dbe22a65a..558213c43b9 100644 --- a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java +++ b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java @@ -155,11 +155,18 @@ public class ConfigSubscriber implements AutoCloseable { * * If the call times out (timeout 1000 ms), no handle will have the changed flag set. You should not configure anything then. * + * @param isInitializing true if this the config is needed to create the initial configuration for the caller, + * false if this is for reconfiguration * @return true if a config/reconfig of your system should happen * @throws ConfigInterruptedException if thread performing this call interrupted. */ + public boolean nextConfig(boolean isInitializing) { + return nextConfig(TimingValues.defaultNextConfigTimeout, isInitializing); + } + + @Deprecated // TODO: Remove on Vespa 8 public boolean nextConfig() { - return nextConfig(TimingValues.defaultNextConfigTimeout); + return nextConfig(false); } /** @@ -179,11 +186,18 @@ public class ConfigSubscriber implements AutoCloseable { * If the call times out, no handle will have the changed flag set. You should not configure anything then. * * @param timeoutMillis timeout in milliseconds + * @param isInitializing true if this the config is needed to create the initial configuration for the caller, + * false if this is for reconfiguration * @return true if a config/reconfig of your system should happen * @throws ConfigInterruptedException if thread performing this call interrupted. */ + public boolean nextConfig(long timeoutMillis, boolean isInitializing) { + return acquireSnapshot(timeoutMillis, true, isInitializing); + } + + @Deprecated // TODO: Remove on Vespa 8 public boolean nextConfig(long timeoutMillis) { - return acquireSnapshot(timeoutMillis, true); + return nextConfig(timeoutMillis, false); } /** @@ -203,11 +217,18 @@ public class ConfigSubscriber implements AutoCloseable { * * If the call times out (timeout 1000 ms), no handle will have the changed flag set. You should not configure anything then. * + * @param isInitializing true if this the next generation is needed to create the initial configuration for the caller, + * false if this is for reconfiguration * @return true if generations for all configs have been updated. * @throws ConfigInterruptedException if thread performing this call interrupted. */ + public boolean nextGeneration(boolean isInitializing) { + return nextGeneration(TimingValues.defaultNextConfigTimeout, isInitializing); + } + + @Deprecated // TODO: Remove on Vespa 8 public boolean nextGeneration() { - return nextGeneration(TimingValues.defaultNextConfigTimeout); + return nextGeneration(false); } /** @@ -227,11 +248,18 @@ public class ConfigSubscriber implements AutoCloseable { * If the call times out (timeout 1000 ms), no handle will have the changed flag set. You should not configure anything then. * * @param timeoutMillis timeout in milliseconds + * @param isInitializing true if this the next generation is needed to create the initial configuration for the caller, + * false if this is for reconfiguration * @return true if generations for all configs have been updated. * @throws ConfigInterruptedException if thread performing this call interrupted. */ + public boolean nextGeneration(long timeoutMillis, boolean isInitializing) { + return acquireSnapshot(timeoutMillis, false, isInitializing); + } + + @Deprecated // TODO: Remov4e on Vespa 8 public boolean nextGeneration(long timeoutMillis) { - return acquireSnapshot(timeoutMillis, false); + return nextGeneration(timeoutMillis, false); } /** @@ -243,14 +271,12 @@ public class ConfigSubscriber implements AutoCloseable { * that at lest one of them has changed if <code>requireChange</code> is true), and * the config should be applied at this time, false otherwise */ - private boolean acquireSnapshot(long timeoutInMillis, boolean requireChange) { - boolean initialConfiguration; + private boolean acquireSnapshot(long timeoutInMillis, boolean requireChange, boolean isInitializing) { boolean applyOnRestartOnly; synchronized (monitor) { if (state == State.CLOSED) return false; state = State.FROZEN; applyOnRestartOnly = applyOnRestart; - initialConfiguration = generation == -1; } long started = System.currentTimeMillis(); long timeLeftMillis = timeoutInMillis; @@ -276,14 +302,14 @@ public class ConfigSubscriber implements AutoCloseable { if (currentGen == null) currentGen = config.getGeneration(); allGenerationsTheSame &= currentGen.equals(config.getGeneration()); allGenerationsChanged &= config.isGenerationChanged(); - anyConfigChanged |= config.isConfigChanged(); + anyConfigChanged |= config.isConfigChanged(); applyOnRestartOnly |= config.applyOnRestart(); timeLeftMillis = timeoutInMillis + started - System.currentTimeMillis(); } - reconfigDue = (initialConfiguration || !applyOnRestartOnly) && (anyConfigChanged || !requireChange) + reconfigDue = (isInitializing || !applyOnRestartOnly) && (anyConfigChanged || !requireChange) && allGenerationsChanged && allGenerationsTheSame; - if (applyOnRestartOnly && ! initialConfiguration) { // disable any reconfig until restart + if (applyOnRestartOnly && ! isInitializing) { // disable any reconfig until restart synchronized (monitor) { applyOnRestart = applyOnRestartOnly; } diff --git a/config/src/test/java/com/yahoo/config/subscription/AppService.java b/config/src/test/java/com/yahoo/config/subscription/AppService.java index 0f8d93e6fe0..3cf301a9b03 100644 --- a/config/src/test/java/com/yahoo/config/subscription/AppService.java +++ b/config/src/test/java/com/yahoo/config/subscription/AppService.java @@ -11,6 +11,7 @@ import com.yahoo.vespa.config.TimingValues; * generated code in AppConfig.java. */ class AppService { + private int timesConfigured = 0; private AppConfig config = null; @@ -33,17 +34,17 @@ class AppService { } else { temp = subscriber.subscribe(AppConfig.class, configId, csource, timingValues); } - final ConfigHandle<AppConfig> handle = temp; + ConfigHandle<AppConfig> handle = temp; Thread configThread = new Thread(() -> { while (!stopThread) { - boolean changed = subscriber.nextConfig(500); + boolean changed = subscriber.nextConfig(500, false); if (changed) { configure(handle.getConfig()); timesConfigured++; } } }); - subscriber.nextConfig(5000); + subscriber.nextConfig(5000, false); timesConfigured++; configure(handle.getConfig()); configThread.setDaemon(true); diff --git a/config/src/test/java/com/yahoo/config/subscription/BasicTest.java b/config/src/test/java/com/yahoo/config/subscription/BasicTest.java index 5b145d40b7f..5af45e3a999 100644 --- a/config/src/test/java/com/yahoo/config/subscription/BasicTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/BasicTest.java @@ -15,7 +15,7 @@ public class BasicTest { public void testSubBasic() { ConfigSubscriber s = new ConfigSubscriber(); ConfigHandle<AppConfig> h = s.subscribe(AppConfig.class, "raw:times 0"); - s.nextConfig(0); + s.nextConfig(0, false); AppConfig c = h.getConfig(); assertEquals(0, c.times()); s.close(); @@ -25,7 +25,7 @@ public class BasicTest { public void testSubBasicGeneration() { ConfigSubscriber s = new ConfigSubscriber(); ConfigHandle<AppConfig> h = s.subscribe(AppConfig.class, "raw:times 2"); - s.nextGeneration(0); + s.nextGeneration(0, false); AppConfig c = h.getConfig(); assertEquals(2, c.times()); s.close(); diff --git a/config/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java b/config/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java index af2df2bcae7..be09e57b27e 100755 --- a/config/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java @@ -23,7 +23,7 @@ public class ConfigApiTest { ConfigSubscriber subscriber = new ConfigSubscriber(); ConfigHandle<AppConfig> h = subscriber.subscribe(AppConfig.class, CONFIG_ID); assertNotNull(h); - subscriber.nextConfig(); + subscriber.nextConfig(false); assertNotNull(h.getConfig()); assertEquals(AppConfig.CONFIG_DEF_NAME, ConfigInstance.getDefName(h.getConfig().getClass())); assertTrue(h.isChanged()); @@ -40,7 +40,7 @@ public class ConfigApiTest { public void testSubscribeAfterClose() { ConfigSubscriber subscriber = new ConfigSubscriber(); subscriber.subscribe(AppConfig.class, CONFIG_ID); - subscriber.nextConfig(); + subscriber.nextConfig(false); subscriber.close(); subscriber.subscribe(AppConfig.class, CONFIG_ID); } @@ -52,7 +52,7 @@ public class ConfigApiTest { public void testSubscribeAfterNextConfig() { ConfigSubscriber subscriber = new ConfigSubscriber(); subscriber.subscribe(AppConfig.class, CONFIG_ID); - subscriber.nextConfig(); + subscriber.nextConfig(false); subscriber.subscribe(AppConfig.class, CONFIG_ID); subscriber.close(); } diff --git a/config/src/test/java/com/yahoo/config/subscription/ConfigInstanceTest.java b/config/src/test/java/com/yahoo/config/subscription/ConfigInstanceTest.java index 4da0c3f51e0..f706f021ba0 100644 --- a/config/src/test/java/com/yahoo/config/subscription/ConfigInstanceTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/ConfigInstanceTest.java @@ -114,8 +114,9 @@ public class ConfigInstanceTest { public TestNonstring(String configId) { ConfigSubscriber subscriber = new ConfigSubscriber(); ConfigHandle<TestNonstringConfig> handle = subscriber.subscribe(TestNonstringConfig.class, configId); - subscriber.nextConfig(); + subscriber.nextConfig(false); handle.getConfig(); } } + } diff --git a/config/src/test/java/com/yahoo/config/subscription/ConfigSetSubscriptionTest.java b/config/src/test/java/com/yahoo/config/subscription/ConfigSetSubscriptionTest.java index db30e7b7389..b31924e94e7 100644 --- a/config/src/test/java/com/yahoo/config/subscription/ConfigSetSubscriptionTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/ConfigSetSubscriptionTest.java @@ -65,7 +65,7 @@ public class ConfigSetSubscriptionTest { ConfigHandle<AppConfig> hA1 = subscriber.subscribe(AppConfig.class, "app/1"); ConfigHandle<StringConfig> hS = subscriber.subscribe(StringConfig.class, "bar"); - assertTrue(subscriber.nextConfig(0)); + assertTrue(subscriber.nextConfig(0, false)); assertTrue(hA0.isChanged()); assertTrue(hA1.isChanged()); assertTrue(hS.isChanged()); @@ -75,7 +75,7 @@ public class ConfigSetSubscriptionTest { assertEquals(hA0.getConfig().times(), 88); assertEquals(hA1.getConfig().times(), 89); - assertFalse(subscriber.nextConfig(10)); + assertFalse(subscriber.nextConfig(10, false)); assertFalse(hA0.isChanged()); assertFalse(hA1.isChanged()); assertFalse(hS.isChanged()); @@ -90,7 +90,7 @@ public class ConfigSetSubscriptionTest { a1builder.message("A new message, 1").times(890); barBuilder.stringVal("new StringVal"); subscriber.reload(1); - assertTrue(subscriber.nextConfig(0)); + assertTrue(subscriber.nextConfig(0, false)); assertTrue(hA0.isChanged()); assertTrue(hA1.isChanged()); assertTrue(hS.isChanged()); @@ -104,7 +104,7 @@ public class ConfigSetSubscriptionTest { // Reconfigure only one a0builder.message("Another new message, 0").times(8800); subscriber.reload(2); - assertTrue(subscriber.nextConfig(0)); + assertTrue(subscriber.nextConfig(0, false)); assertTrue(hA0.isChanged()); assertFalse(hA1.isChanged()); assertFalse(hS.isChanged()); @@ -118,7 +118,7 @@ public class ConfigSetSubscriptionTest { //Reconfigure only one, and only one field on the builder a1builder.message("Yet another message, 1"); subscriber.reload(3); - assertTrue(subscriber.nextConfig(0)); + assertTrue(subscriber.nextConfig(0, false)); assertFalse(hA0.isChanged()); assertTrue(hA1.isChanged()); assertFalse(hS.isChanged()); @@ -139,11 +139,11 @@ public class ConfigSetSubscriptionTest { ConfigSubscriber subscriber = new ConfigSubscriber(myConfigs); ConfigHandle<AppConfig> hA0 = subscriber.subscribe(AppConfig.class, "app/0"); - assertTrue(subscriber.nextConfig(0)); + assertTrue(subscriber.nextConfig(0, false)); assertTrue(hA0.isChanged()); assertEquals(hA0.getConfig().message(), "A message, 1"); - assertFalse(subscriber.nextConfig(10)); + assertFalse(subscriber.nextConfig(10, false)); assertFalse(hA0.isChanged()); assertEquals(hA0.getConfig().message(), "A message, 1"); @@ -154,7 +154,7 @@ public class ConfigSetSubscriptionTest { subscriber.reload(2); // Should pick up the last one - assertTrue(subscriber.nextConfig(0)); + assertTrue(subscriber.nextConfig(0, false)); assertTrue(hA0.isChanged()); assertEquals(hA0.getConfig().message(), "An even newer message, 3"); } diff --git a/config/src/test/java/com/yahoo/config/subscription/ConfigSubscriptionTest.java b/config/src/test/java/com/yahoo/config/subscription/ConfigSubscriptionTest.java index c8d4c081fc9..f70602c64e7 100644 --- a/config/src/test/java/com/yahoo/config/subscription/ConfigSubscriptionTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/ConfigSubscriptionTest.java @@ -68,7 +68,7 @@ public class ConfigSubscriptionTest { ConfigSubscriber sub = new ConfigSubscriber(); ConfigHandle<SimpletypesConfig> handle = sub.subscribe(SimpletypesConfig.class, "raw:boolval true", 10000); assertNotNull(handle); - sub.nextConfig(); + sub.nextConfig(false); assertTrue(handle.getConfig().boolval()); //assertTrue(sub.getSource() instanceof RawSource); sub.close(); diff --git a/config/src/test/java/com/yahoo/config/subscription/DefaultConfigTest.java b/config/src/test/java/com/yahoo/config/subscription/DefaultConfigTest.java index 1bcf09a4028..21bf7469591 100644 --- a/config/src/test/java/com/yahoo/config/subscription/DefaultConfigTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/DefaultConfigTest.java @@ -34,9 +34,8 @@ public class DefaultConfigTest { @Test(expected = IllegalArgumentException.class) public void testFailUponUnitializedValue() { ConfigSubscriber subscriber = new ConfigSubscriber(); - subscriber.subscribe(DefaulttestConfig.class, "raw:" + - "defaultstring \"new value\""); - subscriber.nextConfig(); + subscriber.subscribe(DefaulttestConfig.class, "raw:defaultstring \"new value\""); + subscriber.nextConfig(false); subscriber.close(); } @@ -51,7 +50,7 @@ public class DefaultConfigTest { public void testDefaultConfig() { ConfigSubscriber subscriber = new ConfigSubscriber(); ConfigHandle<DefaulttestConfig> h = subscriber.subscribe(DefaulttestConfig.class, CONFIG_ID); - assertTrue(subscriber.nextConfig()); + assertTrue(subscriber.nextConfig(false)); DefaulttestConfig config = h.getConfig(); verifyConfigValues(config); subscriber.close(); diff --git a/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java b/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java index 9c83f2f3c9a..d5eccdfe94b 100644 --- a/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java @@ -38,10 +38,10 @@ public class GenericConfigSubscriberTest { GenericConfigSubscriber sub = new GenericConfigSubscriber(requesters); final List<String> defContent = List.of("myVal int"); GenericConfigHandle handle = sub.subscribe(new ConfigKey<>("simpletypes", "id", "config"), defContent, sourceSet, JRTConfigRequesterTest.getTestTimingValues()); - assertTrue(sub.nextConfig()); + assertTrue(sub.nextConfig(false)); assertTrue(handle.isChanged()); assertThat(handle.getRawConfig().getPayload().withCompression(CompressionType.UNCOMPRESSED).toString(), is("{}")); // MockConnection returns empty string - assertFalse(sub.nextConfig()); + assertFalse(sub.nextConfig(false)); assertFalse(handle.isChanged()); } |