diff options
Diffstat (limited to 'node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DeprovisionedExpirer.java')
-rw-r--r-- | node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DeprovisionedExpirer.java | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DeprovisionedExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DeprovisionedExpirer.java index c2b383a5a54..92062f13f1a 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DeprovisionedExpirer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DeprovisionedExpirer.java @@ -3,12 +3,19 @@ package com.yahoo.vespa.hosted.provision.maintenance; 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.History; +import com.yahoo.vespa.hosted.provision.node.History.Event.Type; import java.time.Duration; +import java.time.Instant; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.List; +import static java.util.Comparator.comparing; + /** * This removes hosts from {@link com.yahoo.vespa.hosted.provision.Node.State#deprovisioned}, in dynamically provisioned * zones, after a grace period. @@ -17,21 +24,37 @@ import java.util.List; */ public class DeprovisionedExpirer extends Expirer { + private static final int maxDeprovisionedNodes = 1000; + DeprovisionedExpirer(NodeRepository nodeRepository, Duration expiryTime, Metric metric) { super(Node.State.deprovisioned, History.Event.Type.deprovisioned, nodeRepository, expiryTime, metric); } @Override protected boolean isExpired(Node node) { - return nodeRepository().zone().cloud().dynamicProvisioning() && - super.isExpired(node); + return nodeRepository().zone().cloud().dynamicProvisioning() && super.isExpired(node); } @Override - protected void expire(List<Node> expired) { - for (var node : expired) { - nodeRepository().nodes().forget(node); + protected NodeList getExpiredNodes() { + List<Node> deprovisioned = nodeRepository().nodes().list(Node.State.deprovisioned) + .sortedBy(comparing(node -> node.history().event(Type.deprovisioned) + .map(History.Event::at) + .orElse(Instant.EPOCH))) + .asList(); + Deque<Node> expired = new ArrayDeque<>(deprovisioned); + int kept = 0; + while ( ! expired.isEmpty()) { + if (isExpired(expired.getLast()) || kept++ >= maxDeprovisionedNodes) break; // If we encounter an expired node, the rest are also expired. + expired.removeLast(); } + return NodeList.copyOf(List.copyOf(expired)); + } + + @Override + protected void expire(List<Node> expired) { + nodeRepository().nodes().performOn(NodeList.copyOf(expired), + (node, lock) -> { nodeRepository().nodes().forget(node); return node; }); } } |