summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-11-11 10:24:13 +0100
committerHarald Musum <musum@verizonmedia.com>2020-11-11 10:24:13 +0100
commit5123f8e0d1ae631c05410bcaf678023210bbe21e (patch)
treece55bd37c575b73544a9020a97f46db3e920086f
parent601043a29452896635a0122bf20d358f7a02875c (diff)
Hold application lock when redeploying in bootstrap code
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerBootstrap.java26
1 files changed, 20 insertions, 6 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 3275dc42477..3947d45e8d0 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
@@ -235,18 +235,32 @@ public class ConfigServerBootstrap extends AbstractComponent implements Runnable
executor.submit(() -> applicationRepository.deployFromLocalActive(appId, true /* bootstrap */)
.ifPresent(Deployment::activate))));
- Set<ApplicationId> failedDeployments =
- deployments.entrySet().stream()
- .map(entry -> checkDeployment(entry.getKey(), entry.getValue()))
- .filter(Optional::isPresent)
- .map(Optional::get)
- .collect(Collectors.toSet());
+ applicationIds.forEach(appId -> deployments.put(appId, executor.submit(deployWithLock(appId))));
+ Set<ApplicationId> failedDeployments = failedDeployments(deployments);
executor.shutdown();
executor.awaitTermination(365, TimeUnit.DAYS); // Timeout should never happen
return failedDeployments;
}
+ private Set<ApplicationId> failedDeployments(Map<ApplicationId, Future<?>> deployments) {
+ return deployments.entrySet().stream()
+ .map(entry -> checkDeployment(entry.getKey(), entry.getValue()))
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect(Collectors.toSet());
+ }
+
+ // Need to take application lock in case some other config server deploys the application and changes the current active session
+ // If so, the below would fail and retrying might fail if the application package is not available on this server
+ private Runnable deployWithLock(ApplicationId appId) {
+ return () -> {
+ try (var applicationLock = applicationRepository.getTenant(appId).getApplicationRepo().lock(appId)) {
+ applicationRepository.deployFromLocalActive(appId, true /* bootstrap */).ifPresent(Deployment::activate);
+ }
+ };
+ }
+
// Returns an application id if deployment failed
private Optional<ApplicationId> checkDeployment(ApplicationId applicationId, Future<?> future) {
try {