aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2019-01-08 13:21:05 +0100
committerGitHub <noreply@github.com>2019-01-08 13:21:05 +0100
commitdaae47b2e124cb4f657e5beb02ce736339793367 (patch)
treea367e044fc60d74e17876c2ae9dd93e03eb29ed0 /node-repository
parent20b8847e49b85bb146d57fe46af88230f5786279 (diff)
parent0bb150d3684dd84b5f78292a86091e235dc88180 (diff)
Merge pull request #8054 from vespa-engine/mpolden/fix-unstable-comparable
Fix unstable comparable in PeriodicApplicationMaintainer
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java22
1 files changed, 15 insertions, 7 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java
index 8b2d0a55cd8..ff0773fde71 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java
@@ -10,10 +10,11 @@ import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
-import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -48,12 +49,19 @@ public class PeriodicApplicationMaintainer extends ApplicationMaintainer {
protected Set<ApplicationId> applicationsNeedingMaintenance() {
if (waitInitially()) return Collections.emptySet();
- return nodesNeedingMaintenance().stream()
- .map(node -> node.allocation().get().owner())
- .filter(this::shouldBeDeployedOnThisServer)
- .filter(this::canDeployNow)
- .sorted(Comparator.comparing(this::getLastDeployTime))
- .collect(Collectors.toCollection(LinkedHashSet::new));
+ // Collect all deployment times before sorting as deployments may happen while we build the set, breaking
+ // the comparable contract. Stale times are fine as the time is rechecked in ApplicationMaintainer#deployWithLock
+ Map<ApplicationId, Instant> deploymentTimes = nodesNeedingMaintenance().stream()
+ .map(node -> node.allocation().get().owner())
+ .distinct()
+ .filter(this::shouldBeDeployedOnThisServer)
+ .filter(this::canDeployNow)
+ .collect(Collectors.toMap(Function.identity(), this::getLastDeployTime));
+
+ return deploymentTimes.entrySet().stream()
+ .sorted(Map.Entry.comparingByValue())
+ .map(Map.Entry::getKey)
+ .collect(Collectors.toCollection(LinkedHashSet::new));
}
// We only know last deploy time for applications that were deployed on this config server,