diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-09-30 12:11:19 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2021-09-30 12:11:19 +0200 |
commit | 5ed5240a1617659e0a29cb2d574854866516340b (patch) | |
tree | e3c5f51f2c1be9dd3f83a2ab410d09791dc5bde9 /node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java | |
parent | 3fd8cdc2b9a57dd36637b5441dfe07b89cd79ed2 (diff) |
Read nodes once from node repo when starting prepare. Only re-read if noderepo has been modified.
Diffstat (limited to 'node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java')
-rw-r--r-- | node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java index 35fc02d7e5d..76ccac9c618 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java @@ -31,6 +31,18 @@ public class GroupPreparer { private final NodeRepository nodeRepository; private final Optional<HostProvisioner> hostProvisioner; + /** + * Contains list of prepared nodes and the NodesAndHost object to use for next prepare call. + */ + public static class PrepareResult { + public final List<Node> prepared; + public final NodesAndHosts<LockedNodeList> allNodesAndHosts; + PrepareResult(List<Node> prepared, NodesAndHosts<LockedNodeList> allNodesAndHosts) { + this.prepared = prepared; + this.allNodesAndHosts = allNodesAndHosts; + } + } + public GroupPreparer(NodeRepository nodeRepository, Optional<HostProvisioner> hostProvisioner) { this.nodeRepository = nodeRepository; this.hostProvisioner = hostProvisioner; @@ -46,32 +58,39 @@ public class GroupPreparer { * This method will remove from this list if it finds it needs additional nodes * @param indices the next available node indices for this cluster. * This method will consume these when it allocates new nodes to the cluster. - * @return the list of nodes this cluster group will have allocated if activated + * @param allNodesAndHosts list of all nodes and hosts. Use createNodesAndHostUnlocked to create param for + * first invocation. Then use previous PrepareResult.allNodesAndHosts for the following. + * @return the list of nodes this cluster group will have allocated if activated, and */ // Note: This operation may make persisted changes to the set of reserved and inactive nodes, // but it may not change the set of active nodes, as the active nodes must stay in sync with the // active config model which is changed on activate - public List<Node> prepare(ApplicationId application, ClusterSpec cluster, NodeSpec requestedNodes, - List<Node> surplusActiveNodes, NodeIndices indices, int wantedGroups) { + public PrepareResult prepare(ApplicationId application, ClusterSpec cluster, NodeSpec requestedNodes, + List<Node> surplusActiveNodes, NodeIndices indices, int wantedGroups, + NodesAndHosts<LockedNodeList> allNodesAndHosts) { // Try preparing in memory without global unallocated lock. Most of the time there should be no changes and we // can return nodes previously allocated. - NodesAndHosts<LockedNodeList> allNodesAndHosts = NodesAndHosts.create(nodeRepository.nodes().list(PROBE_LOCK)); NodeAllocation probeAllocation = prepareAllocation(application, cluster, requestedNodes, surplusActiveNodes, indices::probeNext, wantedGroups, allNodesAndHosts); if (probeAllocation.fulfilledAndNoChanges()) { List<Node> acceptedNodes = probeAllocation.finalNodes(); surplusActiveNodes.removeAll(acceptedNodes); indices.commitProbe(); - return acceptedNodes; + return new PrepareResult(acceptedNodes, allNodesAndHosts); } else { // There were some changes, so re-do the allocation with locks indices.resetProbe(); - return prepareWithLocks(application, cluster, requestedNodes, surplusActiveNodes, indices, wantedGroups); + List<Node> prepared = prepareWithLocks(application, cluster, requestedNodes, surplusActiveNodes, indices, wantedGroups); + return new PrepareResult(prepared, createNodesAndHostUnlocked()); } } + // Use this to create allNodesAndHosts param to prepare method for first invocation of prepare + public NodesAndHosts<LockedNodeList> createNodesAndHostUnlocked() { return NodesAndHosts.create(nodeRepository.nodes().list(PROBE_LOCK)); } + + /// Note that this will write to the node repo. private List<Node> prepareWithLocks(ApplicationId application, ClusterSpec cluster, NodeSpec requestedNodes, - List<Node> surplusActiveNodes, NodeIndices indices, int wantedGroups) { + List<Node> surplusActiveNodes, NodeIndices indices, int wantedGroups) { try (Mutex lock = nodeRepository.nodes().lock(application); Mutex allocationLock = nodeRepository.nodes().lockUnallocated()) { NodesAndHosts<LockedNodeList> allNodesAndHosts = NodesAndHosts.create(nodeRepository.nodes().list(allocationLock)); |