summaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2020-04-14 12:45:26 +0200
committerGitHub <noreply@github.com>2020-04-14 12:45:26 +0200
commit3884ccf60332bbad772e373aaed15480797f052a (patch)
tree0fb4e28c0438e28be1de56f0d21d111fa2bbe296 /node-repository
parent3988e7df74f7ca9e8496f55037e3fbe36f6577d2 (diff)
Revert "Hold config lock when modifying load balancers"
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java34
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java38
4 files changed, 24 insertions, 68 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
index 1b5b5469302..6f7be09aa0e 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeRepository.java
@@ -5,6 +5,7 @@ import com.google.inject.Inject;
import com.yahoo.collections.ListMap;
import com.yahoo.component.AbstractComponent;
import com.yahoo.component.Version;
+import com.yahoo.vespa.hosted.provision.Node.State;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Flavor;
@@ -16,7 +17,8 @@ import com.yahoo.config.provisioning.NodeRepositoryConfig;
import com.yahoo.transaction.Mutex;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.curator.Curator;
-import com.yahoo.vespa.hosted.provision.Node.State;
+import com.yahoo.vespa.flags.FlagSource;
+import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.hosted.provision.applications.Applications;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancer;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancerId;
@@ -128,9 +130,6 @@ public class NodeRepository extends AbstractComponent {
// read and write all nodes to make sure they are stored in the latest version of the serialized format
for (State state : State.values())
- // TODO(mpolden): Add per-node locking. In its current state this may collide with other callers making
- // node state changes. Example: A redeployment on another config server which moves a node
- // to another state while this is constructed.
db.writeTo(state, db.getNodes(state), Agent.system, Optional.empty());
}
@@ -764,7 +763,6 @@ public class NodeRepository extends AbstractComponent {
public Zone zone() { return zone; }
/** Create a lock which provides exclusive rights to making changes to the given application */
- // TODO(mpolden): Make this delegate to CuratorDatabaseClient#lockConfig instead
public Mutex lock(ApplicationId application) { return db.lock(application); }
/** Create a lock with a timeout which provides exclusive rights to making changes to the given application */
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java
index 7beb717ea8b..e2b70608d58 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirer.java
@@ -120,13 +120,11 @@ public class LoadBalancerExpirer extends Maintainer {
/** Apply operation to all load balancers that exist in given state, while holding lock */
private void withLoadBalancersIn(LoadBalancer.State state, Consumer<LoadBalancer> operation) {
for (var id : db.readLoadBalancerIds()) {
- try (var lock = db.lockConfig(id.application())) {
- try (var legacyLock = db.lockLoadBalancers(id.application())) {
- var loadBalancer = db.readLoadBalancer(id);
- if (loadBalancer.isEmpty()) continue; // Load balancer was removed during loop
- if (loadBalancer.get().state() != state) continue; // Wrong state
- operation.accept(loadBalancer.get());
- }
+ try (var lock = db.lockLoadBalancers(id.application())) {
+ var loadBalancer = db.readLoadBalancer(id);
+ if (loadBalancer.isEmpty()) continue; // Load balancer was removed during loop
+ if (loadBalancer.get().state() != state) continue; // Wrong state
+ operation.accept(loadBalancer.get());
}
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
index 6036cc2366f..8ecdb0cbb1f 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
@@ -62,7 +62,6 @@ public class CuratorDatabaseClient {
private static final Path root = Path.fromString("/provision/v1");
private static final Path lockRoot = root.append("locks");
- private static final Path configLockRoot = Path.fromString("/config/v2/locks/");
private static final Path loadBalancersRoot = root.append("loadBalancers");
private static final Duration defaultLockTimeout = Duration.ofMinutes(2);
@@ -313,7 +312,7 @@ public class CuratorDatabaseClient {
return root.append(toDir(nodeState)).append(nodeName);
}
- /** Creates and returns the path to the lock for this application */
+ /** Creates an returns the path to the lock for this application */
private Path lockPath(ApplicationId application) {
Path lockPath =
lockRoot
@@ -324,14 +323,6 @@ public class CuratorDatabaseClient {
return lockPath;
}
- /** Creates and returns the path to the config server lock for this application */
- private Path configLockPath(ApplicationId application) {
- // This must match the lock path used by com.yahoo.vespa.config.server.application.TenantApplications
- Path lockPath = configLockRoot.append(application.tenant().value()).append(application.serializedForm());
- curatorDatabase.create(lockPath);
- return lockPath;
- }
-
private String toDir(Node.State state) {
switch (state) {
case active: return "allocated"; // legacy name
@@ -367,28 +358,6 @@ public class CuratorDatabaseClient {
}
}
- /**
- * Acquires the single cluster-global, re-entrant config lock for given application. Note that this is the same lock
- * that configserver itself takes when modifying applications.
- *
- * This lock must be taken when writes to paths owned by this class may happen on both the configserver and
- * node-repository side. This behaviour is obviously wrong, but since we pass a NestedTransaction across the
- * configserver and node-repository boundary, the ownership semantics of the transaction (and its operations)
- * becomes unclear.
- *
- * Example of when to use: The config server creates a new transaction and passes the transaction to
- * {@link com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner}, which appends operations to the
- * transaction. The config server then commits (writes) the transaction which may include operations that modify
- * data in paths owned by this class.
- */
- public Lock lockConfig(ApplicationId application) {
- try {
- return lock(configLockPath(application), defaultLockTimeout);
- } catch (UncheckedTimeoutException e) {
- throw new ApplicationLockException(e);
- }
- }
-
private Lock lock(Path path, Duration timeout) {
return curatorDatabase.lock(path, timeout);
}
@@ -556,7 +525,6 @@ public class CuratorDatabaseClient {
transaction.commit();
}
- // TODO(mpolden): Remove this and usages after April 2020
public Lock lockLoadBalancers(ApplicationId application) {
return lock(lockRoot.append("loadBalancersLock2").append(application.serializedForm()), defaultLockTimeout);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
index b694a7c3cd4..1d3fe114e23 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
@@ -52,11 +52,9 @@ public class LoadBalancerProvisioner {
this.service = service;
// Read and write all load balancers to make sure they are stored in the latest version of the serialization format
for (var id : db.readLoadBalancerIds()) {
- try (var lock = db.lockConfig(id.application())) {
- try (var legacyLock = db.lockLoadBalancers(id.application())) {
- var loadBalancer = db.readLoadBalancer(id);
- loadBalancer.ifPresent(db::writeLoadBalancer);
- }
+ try (var lock = db.lockLoadBalancers(id.application())) {
+ var loadBalancer = db.readLoadBalancer(id);
+ loadBalancer.ifPresent(db::writeLoadBalancer);
}
}
}
@@ -75,10 +73,8 @@ public class LoadBalancerProvisioner {
if (requestedNodes.type() != NodeType.tenant) return; // Nothing to provision for this node type
if (!cluster.type().isContainer()) return; // Nothing to provision for this cluster type
if (application.instance().isTester()) return; // Do not provision for tester instances
- try (var lock = db.lockConfig(application)) {
- try (var legacyLock = db.lockLoadBalancers(application)) {
- provision(application, effectiveId(cluster), false, lock);
- }
+ try (var lock = db.lockLoadBalancers(application)) {
+ provision(application, effectiveId(cluster), false, lock);
}
}
@@ -94,17 +90,15 @@ public class LoadBalancerProvisioner {
*/
public void activate(ApplicationId application, Set<ClusterSpec> clusters,
@SuppressWarnings("unused") Mutex applicationLock, NestedTransaction transaction) {
- try (var lock = db.lockConfig(application)) {
- try (var legacyLock = db.lockLoadBalancers(application)) {
- var containerClusters = containerClustersOf(clusters);
- for (var clusterId : containerClusters) {
- // Provision again to ensure that load balancer instance is re-configured with correct nodes
- provision(application, clusterId, true, legacyLock);
- }
- // Deactivate any surplus load balancers, i.e. load balancers for clusters that have been removed
- var surplusLoadBalancers = surplusLoadBalancersOf(application, containerClusters);
- deactivate(surplusLoadBalancers, transaction);
+ try (var lock = db.lockLoadBalancers(application)) {
+ var containerClusters = containerClustersOf(clusters);
+ for (var clusterId : containerClusters) {
+ // Provision again to ensure that load balancer instance is re-configured with correct nodes
+ provision(application, clusterId, true, lock);
}
+ // Deactivate any surplus load balancers, i.e. load balancers for clusters that have been removed
+ var surplusLoadBalancers = surplusLoadBalancersOf(application, containerClusters);
+ deactivate(surplusLoadBalancers, transaction);
}
}
@@ -114,10 +108,8 @@ public class LoadBalancerProvisioner {
*/
public void deactivate(ApplicationId application, NestedTransaction transaction) {
try (var applicationLock = nodeRepository.lock(application)) {
- try (var lock = db.lockConfig(application)) {
- try (var legacyLock = db.lockLoadBalancers(application)) {
- deactivate(nodeRepository.loadBalancers(application).asList(), transaction);
- }
+ try (var lock = db.lockLoadBalancers(application)) {
+ deactivate(nodeRepository.loadBalancers(application).asList(), transaction);
}
}
}