diff options
author | Martin Polden <mpolden@mpolden.no> | 2021-03-16 14:07:57 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2021-03-16 14:07:57 +0100 |
commit | 2d1caee8feba2b6647dcab9ddb0e259d1ce7ff59 (patch) | |
tree | 12bf4c9f163c94db81a266879c46a89825359a9a /node-repository | |
parent | 66d4db0728012bcea58034e0188e24eaef2781c2 (diff) |
Add groupingBy to AbstractFilteringList
Diffstat (limited to 'node-repository')
7 files changed, 43 insertions, 58 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java index 9df6af4d02a..6ff4e1cc20d 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java @@ -6,7 +6,6 @@ import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Deployer; import com.yahoo.jdisc.Metric; -import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.applications.Application; @@ -14,17 +13,15 @@ import com.yahoo.vespa.hosted.provision.applications.Applications; import com.yahoo.vespa.hosted.provision.applications.Cluster; import com.yahoo.vespa.hosted.provision.autoscale.AllocatableClusterResources; import com.yahoo.vespa.hosted.provision.autoscale.Autoscaler; -import com.yahoo.vespa.hosted.provision.autoscale.NodeMetricSnapshot; import com.yahoo.vespa.hosted.provision.autoscale.MetricsDb; +import com.yahoo.vespa.hosted.provision.autoscale.NodeMetricSnapshot; import com.yahoo.vespa.hosted.provision.autoscale.NodeTimeseries; import com.yahoo.vespa.hosted.provision.node.History; import java.time.Duration; import java.time.Instant; -import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; /** * Maintainer making automatic scaling decisions @@ -57,12 +54,12 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer { boolean success = true; if ( ! nodeRepository().zone().environment().isProduction()) return success; - activeNodesByApplication().forEach((applicationId, nodes) -> autoscale(applicationId, nodes)); + activeNodesByApplication().forEach(this::autoscale); return success; } - private void autoscale(ApplicationId application, List<Node> applicationNodes) { - nodesByCluster(applicationNodes).forEach((clusterId, clusterNodes) -> autoscale(application, clusterId, NodeList.copyOf(clusterNodes))); + private void autoscale(ApplicationId application, NodeList applicationNodes) { + nodesByCluster(applicationNodes).forEach((clusterId, clusterNodes) -> autoscale(application, clusterId, clusterNodes)); } private void autoscale(ApplicationId applicationId, ClusterSpec.Id clusterId, NodeList clusterNodes) { @@ -143,8 +140,8 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer { return r + " (total: " + r.totalResources() + ")"; } - private Map<ClusterSpec.Id, List<Node>> nodesByCluster(List<Node> applicationNodes) { - return applicationNodes.stream().collect(Collectors.groupingBy(n -> n.allocation().get().membership().cluster().id())); + private Map<ClusterSpec.Id, NodeList> nodesByCluster(NodeList applicationNodes) { + return applicationNodes.groupingBy(n -> n.allocation().get().membership().cluster().id()); } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintainer.java index e6338d73a17..025c8be449c 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintainer.java @@ -7,13 +7,12 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.NodeType; import com.yahoo.jdisc.Metric; import com.yahoo.vespa.hosted.provision.Node; +import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; import java.time.Clock; import java.time.Duration; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** * A maintainer is some job which runs at a fixed rate to perform some maintenance task on the node repo. @@ -41,13 +40,12 @@ public abstract class NodeRepositoryMaintainer extends Maintainer { protected Clock clock() { return nodeRepository.clock(); } /** A utility to group active tenant nodes by application */ - protected Map<ApplicationId, List<Node>> activeNodesByApplication() { - return nodeRepository().nodes().list(Node.State.active) + protected Map<ApplicationId, NodeList> activeNodesByApplication() { + return nodeRepository().nodes() + .list(Node.State.active) .nodeType(NodeType.tenant) - .asList() - .stream() - .filter(node -> ! node.allocation().get().owner().instance().isTester()) - .collect(Collectors.groupingBy(node -> node.allocation().get().owner())); + .matching(node -> ! node.allocation().get().owner().instance().isTester()) + .groupingBy(node -> node.allocation().get().owner()); } private static JobMetrics jobMetrics(Metric metric) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainer.java index 49a33c4d120..f620a6d113d 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainer.java @@ -5,7 +5,7 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Deployer; import com.yahoo.config.provision.NodeType; import com.yahoo.jdisc.Metric; -import com.yahoo.vespa.hosted.provision.Node; +import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.node.Agent; import com.yahoo.vespa.hosted.provision.node.History; @@ -13,7 +13,6 @@ import com.yahoo.vespa.hosted.provision.node.History; import java.time.Duration; import java.time.Instant; import java.util.LinkedHashSet; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -38,15 +37,14 @@ public class OperatorChangeApplicationMaintainer extends ApplicationMaintainer { @Override protected Set<ApplicationId> applicationsNeedingMaintenance() { - Map<ApplicationId, List<Node>> nodesByApplication = nodeRepository().nodes().list() - .nodeType(NodeType.tenant, NodeType.proxy).asList().stream() - .filter(node -> node.allocation().isPresent()) - .collect(Collectors.groupingBy(node -> node.allocation().get().owner(), Collectors.toList())); - + Map<ApplicationId, NodeList> nodesByApplication = nodeRepository().nodes().list() + .nodeType(NodeType.tenant, NodeType.proxy) + .matching(node -> node.allocation().isPresent()) + .groupingBy(node -> node.allocation().get().owner()); return nodesByApplication.entrySet().stream() - .filter(entry -> hasNodesWithChanges(entry.getKey(), entry.getValue())) - .map(Map.Entry::getKey) - .collect(Collectors.toCollection(LinkedHashSet::new)); + .filter(entry -> hasNodesWithChanges(entry.getKey(), entry.getValue())) + .map(Map.Entry::getKey) + .collect(Collectors.toCollection(LinkedHashSet::new)); } /** @@ -61,15 +59,15 @@ public class OperatorChangeApplicationMaintainer extends ApplicationMaintainer { " as a manual change was made to its nodes"); } - private boolean hasNodesWithChanges(ApplicationId applicationId, List<Node> nodes) { + private boolean hasNodesWithChanges(ApplicationId applicationId, NodeList nodes) { Optional<Instant> lastDeployTime = deployer().lastDeployTime(applicationId); if (lastDeployTime.isEmpty()) return false; return nodes.stream() - .flatMap(node -> node.history().events().stream()) - .filter(event -> event.agent() == Agent.operator) - .map(History.Event::at) - .anyMatch(e -> lastDeployTime.get().isBefore(e)); + .flatMap(node -> node.history().events().stream()) + .filter(event -> event.agent() == Agent.operator) + .map(History.Event::at) + .anyMatch(e -> lastDeployTime.get().isBefore(e)); } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirer.java index 1274e83fb3a..f72daf1bc2b 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirer.java @@ -50,15 +50,10 @@ public class RetiredExpirer extends NodeRepositoryMaintainer { @Override protected boolean maintain() { NodeList activeNodes = nodeRepository().nodes().list(Node.State.active); - - Map<ApplicationId, List<Node>> retiredNodesByApplication = activeNodes.stream() - .filter(node -> node.allocation().isPresent()) - .filter(node -> node.allocation().get().membership().retired()) - .collect(Collectors.groupingBy(node -> node.allocation().get().owner())); - - for (Map.Entry<ApplicationId, List<Node>> entry : retiredNodesByApplication.entrySet()) { + Map<ApplicationId, NodeList> retiredNodesByApplication = activeNodes.retired().groupingBy(node -> node.allocation().get().owner()); + for (Map.Entry<ApplicationId, NodeList> entry : retiredNodesByApplication.entrySet()) { ApplicationId application = entry.getKey(); - List<Node> retiredNodes = entry.getValue(); + NodeList retiredNodes = entry.getValue(); List<Node> nodesToRemove = retiredNodes.stream().filter(n -> canRemove(n, activeNodes)).collect(Collectors.toList()); if (nodesToRemove.isEmpty()) continue; diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ScalingSuggestionsMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ScalingSuggestionsMaintainer.java index 3d6130c4116..e2b89879141 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ScalingSuggestionsMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/ScalingSuggestionsMaintainer.java @@ -7,7 +7,6 @@ import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.jdisc.Metric; import com.yahoo.transaction.Mutex; -import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.applications.Application; @@ -17,10 +16,8 @@ import com.yahoo.vespa.hosted.provision.autoscale.Autoscaler; import com.yahoo.vespa.hosted.provision.autoscale.MetricsDb; import java.time.Duration; -import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; /** * Maintainer computing scaling suggestions for all clusters @@ -49,10 +46,10 @@ public class ScalingSuggestionsMaintainer extends NodeRepositoryMaintainer { return successes > 0; } - private int suggest(ApplicationId application, List<Node> applicationNodes) { + private int suggest(ApplicationId application, NodeList applicationNodes) { int successes = 0; for (var cluster : nodesByCluster(applicationNodes).entrySet()) - successes += suggest(application, cluster.getKey(), NodeList.copyOf(cluster.getValue())) ? 1 : 0; + successes += suggest(application, cluster.getKey(), cluster.getValue()) ? 1 : 0; return successes; } @@ -99,8 +96,8 @@ public class ScalingSuggestionsMaintainer extends NodeRepositoryMaintainer { return r1.totalResources().cost() > r2.totalResources().cost(); } - private Map<ClusterSpec.Id, List<Node>> nodesByCluster(List<Node> applicationNodes) { - return applicationNodes.stream().collect(Collectors.groupingBy(n -> n.allocation().get().membership().cluster().id())); + private Map<ClusterSpec.Id, NodeList> nodesByCluster(NodeList applicationNodes) { + return applicationNodes.groupingBy(n -> n.allocation().get().membership().cluster().id()); } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java index 3c936e4e6ba..49eb44a4ec0 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -100,13 +101,12 @@ class Activator { Optional<Application> application = nodeRepository.applications().get(transaction.application()); if (application.isEmpty()) return; // infrastructure app, hopefully :-| - var currentNodesByCluster = newNodes.stream() - .collect(Collectors.groupingBy(node -> node.allocation().get().membership().cluster().id())); + Map<ClusterSpec.Id, NodeList> currentNodesByCluster = newNodes.groupingBy(node -> node.allocation().get().membership().cluster().id()); Application modified = application.get(); for (var clusterEntry : currentNodesByCluster.entrySet()) { var cluster = modified.cluster(clusterEntry.getKey()).get(); var previousResources = oldNodes.cluster(clusterEntry.getKey()).toResources(); - var currentResources = NodeList.copyOf(clusterEntry.getValue()).toResources(); + var currentResources = clusterEntry.getValue().toResources(); if ( ! previousResources.justNumbers().equals(currentResources.justNumbers())) { cluster = cluster.with(ScalingEvent.create(previousResources, currentResources, generation, at)); } 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 b1bba656dc8..499eb3f23c0 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 @@ -82,7 +82,7 @@ public class LoadBalancerProvisioner { if (application.instance().isTester()) return; // Do not provision for tester instances try (var lock = db.lock(application)) { ClusterSpec.Id clusterId = effectiveId(cluster); - List<Node> nodes = nodesOf(clusterId, application); + NodeList nodes = nodesOf(clusterId, application); LoadBalancerId loadBalancerId = requireNonClashing(new LoadBalancerId(application, clusterId)); ApplicationTransaction transaction = new ApplicationTransaction(new ProvisionLock(application, lock), new NestedTransaction()); provision(transaction, loadBalancerId, nodes, false); @@ -167,7 +167,7 @@ public class LoadBalancerProvisioner { } /** Idempotently provision a load balancer for given application and cluster */ - private void provision(ApplicationTransaction transaction, LoadBalancerId id, List<Node> nodes, boolean activate) { + private void provision(ApplicationTransaction transaction, LoadBalancerId id, NodeList nodes, boolean activate) { Instant now = nodeRepository.clock().instant(); Optional<LoadBalancer> loadBalancer = db.readLoadBalancer(id); if (loadBalancer.isEmpty() && activate) return; // Nothing to activate as this load balancer was never prepared @@ -185,7 +185,7 @@ public class LoadBalancerProvisioner { db.writeLoadBalancers(List.of(newLoadBalancer), transaction.nested()); } - private void provision(ApplicationTransaction transaction, ClusterSpec.Id clusterId, List<Node> nodes) { + private void provision(ApplicationTransaction transaction, ClusterSpec.Id clusterId, NodeList nodes) { provision(transaction, new LoadBalancerId(transaction.application(), clusterId), nodes, true); } @@ -204,12 +204,12 @@ public class LoadBalancerProvisioner { } /** Returns the nodes allocated to the given load balanced cluster */ - private List<Node> nodesOf(ClusterSpec.Id loadBalancedCluster, ApplicationId application) { - return loadBalancedClustersOf(application).getOrDefault(loadBalancedCluster, List.of()); + private NodeList nodesOf(ClusterSpec.Id loadBalancedCluster, ApplicationId application) { + return loadBalancedClustersOf(application).getOrDefault(loadBalancedCluster, NodeList.copyOf(List.of())); } /** Returns the load balanced clusters of given application and their nodes */ - private Map<ClusterSpec.Id, List<Node>> loadBalancedClustersOf(ApplicationId application) { + private Map<ClusterSpec.Id, NodeList> loadBalancedClustersOf(ApplicationId application) { NodeList nodes = nodeRepository.nodes().list(Node.State.reserved, Node.State.active).owner(application); if (nodes.stream().anyMatch(node -> node.type() == NodeType.config)) { nodes = nodes.nodeType(NodeType.config).type(ClusterSpec.Type.admin); @@ -218,11 +218,11 @@ public class LoadBalancerProvisioner { } else { nodes = nodes.nodeType(NodeType.tenant).container(); } - return nodes.stream().collect(Collectors.groupingBy(node -> effectiveId(node.allocation().get().membership().cluster()))); + return nodes.groupingBy(node -> effectiveId(node.allocation().get().membership().cluster())); } /** Returns real servers for given nodes */ - private Set<Real> realsOf(List<Node> nodes) { + private Set<Real> realsOf(NodeList nodes) { var reals = new LinkedHashSet<Real>(); for (var node : nodes) { for (var ip : reachableIpAddresses(node)) { |