diff options
Diffstat (limited to 'container-core/src/main/java/com/yahoo')
3 files changed, 45 insertions, 106 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/handler/ClustersStatus.java b/container-core/src/main/java/com/yahoo/container/handler/ClustersStatus.java deleted file mode 100644 index 19617b46a84..00000000000 --- a/container-core/src/main/java/com/yahoo/container/handler/ClustersStatus.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.yahoo.container.handler; - -import com.google.inject.Inject; -import com.yahoo.component.AbstractComponent; - -import java.util.HashMap; -import java.util.Map; - -/** - * A component which tracks the up/down status of any clusters which should influence - * the up down status of this container itself, as well as the separate fact that such clusters are present. - * - * This is a separate component which has <b>no dependencies</b> such that the status tracked in this - * will survive reconfiguration events and inform other components even immediately after a reconfiguration - * (where the true statue of clusters may not yet be available). - * - * @author bratseth - */ -public class ClustersStatus extends AbstractComponent { - - // NO DEPENDENCIES: Do not add dependencies here - @Inject - public ClustersStatus() { } - - /** Are there any (in-service influencing) clusters in this container? */ - private boolean containerHasClusters; - - /** If we have no clusters, what should we answer? */ - private boolean receiveTrafficByDefault; - - private final Object mutex = new Object(); - - /** The status of clusters, when known. Note that clusters may exist for which there is no knowledge yet. */ - private final Map<Object, Boolean> clusterStatus = new HashMap<>(); - - public void setContainerHasClusters(boolean containerHasClusters) { - synchronized (mutex) { - this.containerHasClusters = containerHasClusters; - if ( ! containerHasClusters) - clusterStatus.clear(); // forget container clusters which was configured away - } - } - - public void setReceiveTrafficByDefault(boolean receiveTrafficByDefault) { - synchronized (mutex) { - this.receiveTrafficByDefault = receiveTrafficByDefault; - } - } - - public void setUp(Object clusterIdentifier) { - synchronized (mutex) { - clusterStatus.put(clusterIdentifier, Boolean.TRUE); - } - } - - public void setDown(Object clusterIdentifier) { - synchronized (mutex) { - clusterStatus.put(clusterIdentifier, Boolean.FALSE); - } - } - - /** Returns whether this container should receive traffic based on the state of this */ - public boolean containerShouldReceiveTraffic() { - synchronized (mutex) { - if (containerHasClusters) { - // Should receive traffic when at least one cluster is up - return clusterStatus.values().stream().anyMatch(status -> status==true); - } - else { - return receiveTrafficByDefault; - } - } - } - -} diff --git a/container-core/src/main/java/com/yahoo/container/handler/VipStatus.java b/container-core/src/main/java/com/yahoo/container/handler/VipStatus.java index be386b1b84e..d7457140dae 100644 --- a/container-core/src/main/java/com/yahoo/container/handler/VipStatus.java +++ b/container-core/src/main/java/com/yahoo/container/handler/VipStatus.java @@ -15,56 +15,70 @@ import com.yahoo.container.core.VipStatusConfig; */ public class VipStatus { - private final ClustersStatus clustersStatus; - - /** If this is non-null, its value decides whether this container is in rotation */ - private Boolean inRotationOverride; + private final Map<Object, Boolean> clusters = new IdentityHashMap<>(); + private final VipStatusConfig vipStatusConfig; public VipStatus() { - this(new QrSearchersConfig(new QrSearchersConfig.Builder()), - new VipStatusConfig(new VipStatusConfig.Builder()), - new ClustersStatus()); + this(null, new VipStatusConfig(new VipStatusConfig.Builder())); } public VipStatus(QrSearchersConfig dispatchers) { - this(dispatchers, new VipStatusConfig(new VipStatusConfig.Builder()), new ClustersStatus()); - } - - public VipStatus(ClustersStatus clustersStatus) { - this.clustersStatus = clustersStatus; + this(dispatchers, new VipStatusConfig(new VipStatusConfig.Builder())); } + // TODO: Why use QrSearchersConfig here? Remove and inject ComponentRegistry<ClusterSearcher> instead? @Inject - public VipStatus(QrSearchersConfig dispatchers, VipStatusConfig vipStatusConfig, ClustersStatus clustersStatus) { - this.clustersStatus = clustersStatus; - clustersStatus.setReceiveTrafficByDefault(vipStatusConfig.initiallyInRotation()); - clustersStatus.setContainerHasClusters(! dispatchers.searchcluster().isEmpty()); + public VipStatus(QrSearchersConfig dispatchers, VipStatusConfig vipStatusConfig) { + // the config is not used for anything, it's just a dummy to create a + // dependency link to which dispatchers are used + this.vipStatusConfig = vipStatusConfig; } /** - * Explicitly set this container in or out of rotation + * Set a service or cluster into rotation. * - * @param inRotation true to set this in rotation regardless of any clusters and of the default value, - * false to set it out, and null to make this decision using the usual cluster-dependent logic + * @param clusterIdentifier + * an object where the object identity will serve to identify the + * cluster or service */ - public void setInRotation(Boolean inRotation) { - this.inRotationOverride = inRotation; - } - - /** Note that a cluster (which influences up/down state) is up */ public void addToRotation(Object clusterIdentifier) { - clustersStatus.setUp(clusterIdentifier); + synchronized (clusters) { + clusters.put(clusterIdentifier, Boolean.TRUE); + } } - /** Note that a cluster (which influences up/down state) is down */ + /** + * Set a service or cluster out of rotation. + * + * @param clusterIdentifier + * an object where the object identity will serve to identify the + * cluster or service + */ public void removeFromRotation(Object clusterIdentifier) { - clustersStatus.setDown(clusterIdentifier); + synchronized (clusters) { + clusters.put(clusterIdentifier, Boolean.FALSE); + } } - /** Returns whether this container should receive traffic at this time */ + /** + * Tell whether the container is connected to any active services at all. + * + * @return true if at least one service or cluster is up, or value is taken from config if no services + * are registered (yet) + */ public boolean isInRotation() { - if (inRotationOverride != null) return inRotationOverride; - return clustersStatus.containerShouldReceiveTraffic(); + synchronized (clusters) { + // if no stored state, use config to decide whether to serve or not + if (clusters.size() == 0) { + return vipStatusConfig.initiallyInRotation(); + } + for (Boolean inRotation : clusters.values()) { + if (inRotation) { + return true; + } + } + } + return false; } } diff --git a/container-core/src/main/java/com/yahoo/container/handler/VipStatusHandler.java b/container-core/src/main/java/com/yahoo/container/handler/VipStatusHandler.java index 60affddeb60..b7977e7832d 100644 --- a/container-core/src/main/java/com/yahoo/container/handler/VipStatusHandler.java +++ b/container-core/src/main/java/com/yahoo/container/handler/VipStatusHandler.java @@ -49,7 +49,7 @@ public final class VipStatusHandler extends ThreadedHttpRequestHandler { class StatusResponse extends HttpResponse { static final String COULD_NOT_FIND_STATUS_FILE = "Could not find status file.\n"; - static final String NO_SEARCH_BACKENDS = "No search backends available, VIP status disabled."; // TODO: Generify + static final String NO_SEARCH_BACKENDS = "No search backends available, VIP status disabled."; private static final String TEXT_HTML = "text/html"; private String contentType = TEXT_HTML; private byte[] data = null; |