summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2021-01-07 17:25:54 +0100
committerHarald Musum <musum@verizonmedia.com>2021-01-07 17:25:54 +0100
commit45a78adec61d5fd41c1f6122c08b0c153b1c45fd (patch)
tree0efc9bb78fccb1e270a745159c84139445d9b6fc /configserver
parentde747f7296327a96b5f298f7f0f3905f91dfb8ba (diff)
Synchronize when creating application package
Synchronize to avoid threads trying to create an application package concurrently (e.g. a maintainer and an external deployment)
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java8
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java37
2 files changed, 25 insertions, 20 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
index f1775492003..5609de68391 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
@@ -47,10 +47,7 @@ import com.yahoo.vespa.config.server.tenant.EndpointCertificateRetriever;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.curator.Curator;
import com.yahoo.vespa.flags.FlagSource;
-import org.xml.sax.SAXException;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerException;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
@@ -174,11 +171,11 @@ public class SessionPreparer {
Preparation(HostValidator<ApplicationId> hostValidator, DeployLogger logger, PrepareParams params,
Optional<ApplicationSet> currentActiveApplicationSet, Path tenantPath,
- File serverDbSessionDir, ApplicationPackage preprocessedApplicationPackage,
+ File serverDbSessionDir, ApplicationPackage applicationPackage,
SessionZooKeeperClient sessionZooKeeperClient) {
this.logger = logger;
this.params = params;
- this.applicationPackage = preprocessedApplicationPackage;
+ this.applicationPackage = applicationPackage;
this.sessionZooKeeperClient = sessionZooKeeperClient;
this.applicationId = params.getApplicationId();
this.dockerImageRepository = params.dockerImageRepository();
@@ -402,6 +399,7 @@ public class SessionPreparer {
* This class ensures these constraints and returns a reconciliated set of nodes which should be activated,
* given a set of model activation results.
*/
+ @SuppressWarnings("unused")
private static final class ReconciliatedHostAllocations {
public ReconciliatedHostAllocations(List<PreparedModelsBuilder.PreparedModelResult> results) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
index 64b757037d0..592198cbbef 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
@@ -73,6 +73,7 @@ public class SessionRepository {
private static final FilenameFilter sessionApplicationsFilter = (dir, name) -> name.matches("\\d+");
private static final long nonExistingActiveSessionId = 0;
+ private final Object monitor = new Object();
private final Map<Long, LocalSession> localSessionCache = new ConcurrentHashMap<>();
private final Map<Long, RemoteSession> remoteSessionCache = new ConcurrentHashMap<>();
private final Map<Long, SessionStateWatcher> sessionStateWatchers = new HashMap<>();
@@ -202,8 +203,8 @@ public class SessionRepository {
}
/**
- * This method is used when creating a session based on a remote session and the distributed application package
- * It does not wait for session being created on other servers
+ * Creates a local session based on a remote session and the distributed application package.
+ * Does not wait for session being created on other servers.
*/
private void createLocalSession(File applicationFile, ApplicationId applicationId, long sessionId) {
try {
@@ -548,19 +549,25 @@ public class SessionRepository {
}
}
- private ApplicationPackage createApplicationPackage(File applicationFile, ApplicationId applicationId,
- long sessionId, boolean internalRedeploy) throws IOException {
- Optional<Long> activeSessionId = getActiveSessionId(applicationId);
- File userApplicationDir = getSessionAppDir(sessionId);
- copyApp(applicationFile, userApplicationDir);
- ApplicationPackage applicationPackage = createApplication(applicationFile,
- userApplicationDir,
- applicationId,
- sessionId,
- activeSessionId,
- internalRedeploy);
- applicationPackage.writeMetaData();
- return applicationPackage;
+ private ApplicationPackage createApplicationPackage(File applicationFile,
+ ApplicationId applicationId,
+ long sessionId,
+ boolean internalRedeploy) throws IOException {
+ // Synchronize to avoid threads trying to create an application package concurrently
+ // (e.g. a maintainer and an external deployment)
+ synchronized (monitor) {
+ Optional<Long> activeSessionId = getActiveSessionId(applicationId);
+ File userApplicationDir = getSessionAppDir(sessionId);
+ copyApp(applicationFile, userApplicationDir);
+ ApplicationPackage applicationPackage = createApplication(applicationFile,
+ userApplicationDir,
+ applicationId,
+ sessionId,
+ activeSessionId,
+ internalRedeploy);
+ applicationPackage.writeMetaData();
+ return applicationPackage;
+ }
}
public Optional<ApplicationSet> getActiveApplicationSet(ApplicationId appId) {