summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java57
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java66
2 files changed, 64 insertions, 59 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index b14fe5bcac9..8a02383ad0b 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -6,7 +6,6 @@ import com.google.inject.Inject;
import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.component.Version;
import com.yahoo.component.Vtag;
-import com.yahoo.concurrent.DaemonThreadFactory;
import com.yahoo.config.FileReference;
import com.yahoo.config.application.api.ApplicationFile;
import com.yahoo.config.application.api.ApplicationMetaData;
@@ -62,17 +61,10 @@ import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
-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.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -460,7 +452,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
}
}
- private Set<ApplicationId> listApplications() {
+ Set<ApplicationId> listApplications() {
return tenantRepository.getAllTenants().stream()
.flatMap(tenant -> tenant.getApplicationRepo().listApplications().stream())
.collect(Collectors.toSet());
@@ -684,53 +676,6 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
}
}
- boolean redeployAllApplications(Duration maxDuration, Duration sleepBetweenRetries) throws InterruptedException {
- Instant end = Instant.now().plus(maxDuration);
- Set<ApplicationId> applicationsNotRedeployed = listApplications();
- do {
- applicationsNotRedeployed = redeployApplications(applicationsNotRedeployed);
- if ( ! applicationsNotRedeployed.isEmpty()) {
- Thread.sleep(sleepBetweenRetries.toMillis());
- }
- } while ( ! applicationsNotRedeployed.isEmpty() && Instant.now().isBefore(end));
-
- if ( ! applicationsNotRedeployed.isEmpty()) {
- log.log(LogLevel.ERROR, "Redeploying applications not finished after " + maxDuration +
- ", exiting, applications that failed redeployment: " + applicationsNotRedeployed);
- return false;
- }
- return true;
- }
-
- // Returns the set of applications that failed to redeploy
- private Set<ApplicationId> redeployApplications(Set<ApplicationId> applicationIds) throws InterruptedException {
- ExecutorService executor = Executors.newFixedThreadPool(configserverConfig.numParallelTenantLoaders(),
- new DaemonThreadFactory("redeploy apps"));
- // Keep track of deployment per application
- Map<ApplicationId, Future<?>> futures = new HashMap<>();
- Set<ApplicationId> failedDeployments = new HashSet<>();
-
- for (ApplicationId appId : applicationIds) {
- Optional<com.yahoo.config.provision.Deployment> deploymentOptional = deployFromLocalActive(appId, true /* bootstrap */);
- if ( ! deploymentOptional.isPresent()) continue;
-
- futures.put(appId, executor.submit(deploymentOptional.get()::activate));
- }
-
- for (Map.Entry<ApplicationId, Future<?>> f : futures.entrySet()) {
- try {
- f.getValue().get();
- } catch (ExecutionException e) {
- ApplicationId app = f.getKey();
- log.log(LogLevel.WARNING, "Redeploying " + app + " failed, will retry", e);
- failedDeployments.add(app);
- }
- }
- executor.shutdown();
- executor.awaitTermination(365, TimeUnit.DAYS); // Timeout should never happen
- return failedDeployments;
- }
-
private LocalSession getExistingSession(Tenant tenant, ApplicationId applicationId) {
TenantApplications applicationRepo = tenant.getApplicationRepo();
return getLocalSession(tenant, applicationRepo.getSessionIdForApplication(applicationId));
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 50052ac856c..46be61964ce 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
@@ -2,8 +2,11 @@
package com.yahoo.vespa.config.server;
import com.google.inject.Inject;
+import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.component.AbstractComponent;
import com.yahoo.concurrent.DaemonThreadFactory;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.Deployment;
import com.yahoo.container.handler.VipStatus;
import com.yahoo.container.jdisc.state.StateMonitor;
import com.yahoo.log.LogLevel;
@@ -12,8 +15,16 @@ import com.yahoo.vespa.config.server.version.VersionState;
import java.time.Duration;
import java.time.Instant;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
/**
* Main component that bootstraps and starts config server threads.
@@ -39,6 +50,7 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
private final VersionState versionState;
private final StateMonitor stateMonitor;
private final VipStatus vipStatus;
+ private final ConfigserverConfig configserverConfig;
private final Duration maxDurationOfRedeployment;
private final Duration sleepTimeWhenRedeployingFails;
private final RedeployingApplicationsFails exitIfRedeployingApplicationsFails;
@@ -63,8 +75,9 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
this.stateMonitor = stateMonitor;
this.serverThread = new Thread(this, "configserver main");
this.vipStatus = vipStatus;
- this.maxDurationOfRedeployment = Duration.ofSeconds(applicationRepository.configserverConfig().maxDurationOfBootstrap());
- this.sleepTimeWhenRedeployingFails = Duration.ofSeconds(applicationRepository.configserverConfig().sleepTimeWhenRedeployingFails());
+ this.configserverConfig = applicationRepository.configserverConfig();
+ this.maxDurationOfRedeployment = Duration.ofSeconds(configserverConfig.maxDurationOfBootstrap());
+ this.sleepTimeWhenRedeployingFails = Duration.ofSeconds(configserverConfig.sleepTimeWhenRedeployingFails());
this.exitIfRedeployingApplicationsFails = exitIfRedeployingApplicationsFails;
rpcServerExecutor = Executors.newSingleThreadExecutor(new DaemonThreadFactory("config server RPC server"));
initializing(); // Initially take server out of rotation
@@ -91,7 +104,7 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
log.log(LogLevel.INFO, "Configserver upgrading from " + versionState.storedVersion() + " to "
+ versionState.currentVersion() + ". Redeploying all applications");
try {
- if ( ! applicationRepository.redeployAllApplications(maxDurationOfRedeployment, sleepTimeWhenRedeployingFails)) {
+ if ( ! redeployAllApplications()) {
redeployingApplicationsFailed();
return; // Status will not be set to 'up' since we return here
}
@@ -163,5 +176,52 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
if (exitIfRedeployingApplicationsFails == RedeployingApplicationsFails.EXIT_JVM) System.exit(1);
}
+ private boolean redeployAllApplications() throws InterruptedException {
+ Instant end = Instant.now().plus(maxDurationOfRedeployment);
+ Set<ApplicationId> applicationsNotRedeployed = applicationRepository.listApplications();
+ do {
+ applicationsNotRedeployed = redeployApplications(applicationsNotRedeployed);
+ if ( ! applicationsNotRedeployed.isEmpty()) {
+ Thread.sleep(sleepTimeWhenRedeployingFails.toMillis());
+ }
+ } while ( ! applicationsNotRedeployed.isEmpty() && Instant.now().isBefore(end));
+
+ if ( ! applicationsNotRedeployed.isEmpty()) {
+ log.log(LogLevel.ERROR, "Redeploying applications not finished after " + maxDurationOfRedeployment +
+ ", exiting, applications that failed redeployment: " + applicationsNotRedeployed);
+ return false;
+ }
+ return true;
+ }
+
+ // Returns the set of applications that failed to redeploy
+ private Set<ApplicationId> redeployApplications(Set<ApplicationId> applicationIds) throws InterruptedException {
+ ExecutorService executor = Executors.newFixedThreadPool(configserverConfig.numParallelTenantLoaders(),
+ new DaemonThreadFactory("redeploy apps"));
+ // Keep track of deployment per application
+ Map<ApplicationId, Future<?>> futures = new HashMap<>();
+ Set<ApplicationId> failedDeployments = new HashSet<>();
+
+ for (ApplicationId appId : applicationIds) {
+ Optional<Deployment> deploymentOptional = applicationRepository.deployFromLocalActive(appId, true /* bootstrap */);
+ if ( ! deploymentOptional.isPresent()) continue;
+
+ futures.put(appId, executor.submit(deploymentOptional.get()::activate));
+ }
+
+ for (Map.Entry<ApplicationId, Future<?>> f : futures.entrySet()) {
+ try {
+ f.getValue().get();
+ } catch (ExecutionException e) {
+ ApplicationId app = f.getKey();
+ log.log(LogLevel.WARNING, "Redeploying " + app + " failed, will retry", e);
+ failedDeployments.add(app);
+ }
+ }
+ executor.shutdown();
+ executor.awaitTermination(365, TimeUnit.DAYS); // Timeout should never happen
+ return failedDeployments;
+ }
+
}