diff options
author | Håkon Hallingstad <hakon@yahooinc.com> | 2023-10-25 14:14:07 +0200 |
---|---|---|
committer | Håkon Hallingstad <hakon@yahooinc.com> | 2023-10-25 14:14:07 +0200 |
commit | 229648eef11a91f3ade59acbbe42776f1e3ed029 (patch) | |
tree | 2936fae28ec3d36ef9f80896816480348b623c55 | |
parent | 2695d14822d91b0e00c4c46ae4fbdcca707a327f (diff) |
Take parent lock only for tenant app in GCP/AWS
3 files changed, 29 insertions, 5 deletions
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeType.java b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeType.java index 266ede04800..0eac568ec45 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeType.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeType.java @@ -88,6 +88,14 @@ public enum NodeType { return childNodeTypes.contains(type); } + /** Returns the parent host type. */ + public NodeType parentNodeType() { + for (var type : values()) { + if (type.childNodeTypes.contains(this)) return type; + } + throw new IllegalStateException(this + " has no parent"); + } + /** Returns the host type of this */ public NodeType hostType() { if (isHost()) return this; @@ -97,7 +105,7 @@ public enum NodeType { return nodeType; } } - throw new IllegalArgumentException("No host of " + this + " exists"); + throw new IllegalStateException("No host of " + this + " exists"); } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeCandidate.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeCandidate.java index 10a8460614f..179d88d33ab 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeCandidate.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeCandidate.java @@ -628,7 +628,9 @@ public abstract class NodeCandidate implements Nodelike, Comparable<NodeCandidat // this cluster requires exclusivity, but the parent is not exclusive if (exclusiveAllocation && parent.flatMap(Node::exclusiveToApplicationId).isEmpty()) - return makeExclusive ? ExclusivityViolation.PARENT_HOST_NOT_EXCLUSIVE : ExclusivityViolation.YES; + return Preparer.requireParentHostLock(makeExclusive, type(), hostSharing) ? + ExclusivityViolation.PARENT_HOST_NOT_EXCLUSIVE : + ExclusivityViolation.YES; } return ExclusivityViolation.NONE; diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java index 9f5775ee8c3..fad42449285 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java @@ -92,10 +92,24 @@ public class Preparer { } } + /** + * Whether the preparation of an application MAY require changes to the parent hosts, and therefore the parent host lock is required. + * See {@link NodeCandidate#withExclusiveParent(boolean)}. + */ + public static boolean requireParentHostLock(boolean makeExclusive, NodeType type, boolean allowHostSharing) { + return makeExclusive && type == NodeType.tenant && !allowHostSharing; + } + + private ApplicationMutex parentLockOrNull(boolean makeExclusive, NodeType type) { + return requireParentHostLock(makeExclusive, type, nodeRepository.zone().cloud().allowHostSharing()) ? + nodeRepository.applications().lock(InfrastructureApplication.withNodeType(type.parentNodeType()).id()) : + null; + } + /// Note that this will write to the node repo. private List<Node> prepareWithLocks(ApplicationId application, ClusterSpec cluster, NodeSpec requested, NodeIndices indices, boolean makeExclusive) { try (Mutex lock = nodeRepository.applications().lock(application); - ApplicationMutex tenantHostLock = makeExclusive ? nodeRepository.applications().lock(InfrastructureApplication.TENANT_HOST.id()) : null; + ApplicationMutex parentLockOrNull = parentLockOrNull(makeExclusive, requested.type()); Mutex allocationLock = nodeRepository.nodes().lockUnallocated()) { LockedNodeList allNodes = nodeRepository.nodes().list(allocationLock); NodeAllocation allocation = prepareAllocation(application, cluster, requested, indices::next, allNodes, makeExclusive); @@ -158,9 +172,9 @@ public class Preparer { allocation.allocationFailureDetails(), true); // Carry out and return allocation - if (tenantHostLock != null) { + if (parentLockOrNull != null) { List<Node> exclusiveParents = allocation.parentsRequiredToBeExclusive(); - nodeRepository.nodes().setExclusiveToApplicationId(exclusiveParents, tenantHostLock); + nodeRepository.nodes().setExclusiveToApplicationId(exclusiveParents, parentLockOrNull); // TODO: also update tags } List<Node> acceptedNodes = allocation.finalNodes(); |