diff options
author | Harald Musum <musum@oath.com> | 2018-12-06 11:06:35 +0100 |
---|---|---|
committer | Harald Musum <musum@oath.com> | 2018-12-06 11:06:35 +0100 |
commit | e8413a1891fb4e62e9d09d8a0d3b6ed41cea52b9 (patch) | |
tree | e462b42f09427406df9a5c7d51b81c17eb7087d3 /configserver | |
parent | 75276d4828add1bf65718e91b4eac19165f14a6c (diff) |
Make it configurable if bootstrap is done in separate thread
Default value for config is true (unchanged from how we do it today)
Diffstat (limited to 'configserver')
-rw-r--r-- | configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java | 70 | ||||
-rw-r--r-- | configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java | 10 |
2 files changed, 51 insertions, 29 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java index 7ec93c0cf98..f163a100fd8 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java @@ -15,6 +15,7 @@ import com.yahoo.vespa.config.server.version.VersionState; import java.time.Duration; import java.time.Instant; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -40,12 +41,12 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(ConfigServerBootstrap.class.getName()); - enum MainThread {START, DO_NOT_START} + enum Mode {BOOTSTRAP_IN_CONSTRUCTOR, BOOTSTRAP_IN_SEPARATE_THREAD, INITIALIZE_ONLY} // INITIALIZE_ONLY is for testing only enum RedeployingApplicationsFails {EXIT_JVM, CONTINUE} private final ApplicationRepository applicationRepository; private final RpcServer server; - private final Thread serverThread; + private final Optional<Thread> serverThread; private final VersionState versionState; private final StateMonitor stateMonitor; private final VipStatus vipStatus; @@ -61,18 +62,19 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable @Inject public ConfigServerBootstrap(ApplicationRepository applicationRepository, RpcServer server, VersionState versionState, StateMonitor stateMonitor, VipStatus vipStatus) { - this(applicationRepository, server, versionState, stateMonitor, vipStatus, MainThread.START, RedeployingApplicationsFails.EXIT_JVM); + this(applicationRepository, server, versionState, stateMonitor, vipStatus, + applicationRepository.configserverConfig().bootstrapInSeparateThread () ? Mode.BOOTSTRAP_IN_SEPARATE_THREAD : Mode.BOOTSTRAP_IN_CONSTRUCTOR, + RedeployingApplicationsFails.EXIT_JVM); } // For testing only ConfigServerBootstrap(ApplicationRepository applicationRepository, RpcServer server, VersionState versionState, - StateMonitor stateMonitor, VipStatus vipStatus, MainThread mainThread, + StateMonitor stateMonitor, VipStatus vipStatus, Mode mode, RedeployingApplicationsFails exitIfRedeployingApplicationsFails) { this.applicationRepository = applicationRepository; this.server = server; this.versionState = versionState; this.stateMonitor = stateMonitor; - this.serverThread = new Thread(this, "configserver main"); this.vipStatus = vipStatus; this.configserverConfig = applicationRepository.configserverConfig(); this.maxDurationOfRedeployment = Duration.ofSeconds(configserverConfig.maxDurationOfBootstrap()); @@ -80,8 +82,22 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable this.exitIfRedeployingApplicationsFails = exitIfRedeployingApplicationsFails; rpcServerExecutor = Executors.newSingleThreadExecutor(new DaemonThreadFactory("config server RPC server")); initializing(); // Initially take server out of rotation - if (mainThread == MainThread.START) - start(); + log.log(LogLevel.INFO, "Mode: " + mode); + switch (mode) { + case BOOTSTRAP_IN_SEPARATE_THREAD: + this.serverThread = Optional.of(new Thread(this, "config server bootstrap thread")); + serverThread.get().start(); + break; + case BOOTSTRAP_IN_CONSTRUCTOR: + this.serverThread = Optional.empty(); + start(); + break; + case INITIALIZE_ONLY: + this.serverThread = Optional.empty(); + break; + default: + throw new IllegalArgumentException("Unknown mode " + mode + ", legal values: " + Arrays.toString(Mode.values())); + } } @Override @@ -89,16 +105,32 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable log.log(LogLevel.INFO, "Stopping config server"); down(); server.stop(); + log.log(LogLevel.INFO, "RPC server stopped"); rpcServerExecutor.shutdown(); - try { - serverThread.join(); - } catch (InterruptedException e) { - log.log(LogLevel.WARNING, "Error joining server thread on shutdown: " + e.getMessage()); - } + serverThread.ifPresent(thread -> { + try { + thread.join(); + } catch (InterruptedException e) { + log.log(LogLevel.WARNING, "Error joining server thread on shutdown: " + e.getMessage()); + } + }); } @Override public void run() { + start(); + do { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + log.log(LogLevel.ERROR, "Got interrupted", e); + break; + } + } while (server.isRunning()); + down(); + } + + public void start() { if (versionState.isUpgraded()) { log.log(LogLevel.INFO, "Configserver upgrading from " + versionState.storedVersion() + " to " + versionState.currentVersion() + ". Redeploying all applications"); @@ -117,26 +149,12 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable } startRpcServer(); up(); - do { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - log.log(LogLevel.ERROR, "Got interrupted", e); - break; - } - } while (server.isRunning()); - down(); - log.log(LogLevel.INFO, "RPC server stopped"); } StateMonitor.Status status() { return stateMonitor.status(); } - private void start() { - serverThread.start(); - } - private void up() { stateMonitor.status(StateMonitor.Status.up); vipStatus.setInRotation(true); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java index bc7c090482e..6030ac1ac9f 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java @@ -66,8 +66,12 @@ public class ConfigServerBootstrapTest { VipStatus vipStatus = new VipStatus(); // Take a host away so that there are too few for the application, to verify we can still bootstrap provisioner.allocations().values().iterator().next().remove(0); - ConfigServerBootstrap bootstrap = new ConfigServerBootstrap(tester.applicationRepository(), rpcServer, versionState, createStateMonitor(), vipStatus); + ConfigServerBootstrap bootstrap = new ConfigServerBootstrap(tester.applicationRepository(), rpcServer, + versionState, createStateMonitor(), vipStatus, + ConfigServerBootstrap.Mode.INITIALIZE_ONLY, + ConfigServerBootstrap.RedeployingApplicationsFails.CONTINUE); assertFalse(vipStatus.isInRotation()); + bootstrap.start(); waitUntil(rpcServer::isRunning, "failed waiting for Rpc server running"); waitUntil(() -> bootstrap.status() == StateMonitor.Status.up, "failed waiting for status 'up'"); waitUntil(vipStatus::isInRotation, "failed waiting for server to be in rotation"); @@ -98,11 +102,11 @@ public class ConfigServerBootstrapTest { VipStatus vipStatus = new VipStatus(); ConfigServerBootstrap bootstrap = new ConfigServerBootstrap(tester.applicationRepository(), rpcServer, versionState, createStateMonitor(), vipStatus, - ConfigServerBootstrap.MainThread.DO_NOT_START, + ConfigServerBootstrap.Mode.INITIALIZE_ONLY, ConfigServerBootstrap.RedeployingApplicationsFails.CONTINUE); assertFalse(vipStatus.isInRotation()); // Call method directly, to be sure that it is finished redeploying all applications and we can check status - bootstrap.run(); + bootstrap.start(); // App is invalid, bootstrapping was unsuccessful. Status should be 'initializing', // rpc server should not be running and it should be out of rotation assertEquals(StateMonitor.Status.initializing, bootstrap.status()); |