diff options
3 files changed, 32 insertions, 8 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 index 23d219df340..16c2677e1b6 100644 --- a/container-core/src/main/java/com/yahoo/container/handler/ClustersStatus.java +++ b/container-core/src/main/java/com/yahoo/container/handler/ClustersStatus.java @@ -15,6 +15,8 @@ import java.util.Map; * will survive reconfiguration events and inform other components even immediately after a reconfiguration * (where the true statue of clusters may not yet be available). * + * This is multithread safe. + * * @author bratseth */ public class ClustersStatus extends AbstractComponent { 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 a0a27ec942f..555dc81057d 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 @@ -8,14 +8,22 @@ import com.yahoo.container.core.VipStatusConfig; /** * API for programmatically removing the container from VIP rotation. * + * This is multithread safe. + * * @author Steinar Knutsen + * @author bratseth */ 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 Boolean rotationOverride = null; + + /** The current state of this */ + private boolean currentlyInRotation; + + private final Object mutex = new Object(); public VipStatus() { this(new QrSearchersConfig(new QrSearchersConfig.Builder()), @@ -35,6 +43,7 @@ public class VipStatus { public VipStatus(QrSearchersConfig dispatchers, ClustersStatus clustersStatus) { this.clustersStatus = clustersStatus; clustersStatus.setContainerHasClusters(! dispatchers.searchcluster().isEmpty()); + updateCurrentlyInRotation(); } /** @deprecated don't pass VipStatusConfig */ @@ -50,17 +59,22 @@ public class VipStatus { * false to set it out, and null to make this decision using the usual cluster-dependent logic */ public void setInRotation(Boolean inRotation) { - this.inRotationOverride = inRotation; + synchronized (mutex) { + rotationOverride = inRotation; + updateCurrentlyInRotation(); + } } /** Note that a cluster (which influences up/down state) is up */ public void addToRotation(String clusterIdentifier) { clustersStatus.setUp(clusterIdentifier); + updateCurrentlyInRotation(); } /** Note that a cluster (which influences up/down state) is down */ public void removeFromRotation(String clusterIdentifier) { clustersStatus.setDown(clusterIdentifier); + updateCurrentlyInRotation(); } /** @deprecated use addToRotation(String) instead */ @@ -75,10 +89,18 @@ public class VipStatus { removeFromRotation((String) clusterIdentifier); } + private void updateCurrentlyInRotation() { + synchronized (mutex) { + if (rotationOverride != null) + currentlyInRotation = rotationOverride; + else + currentlyInRotation = clustersStatus.containerShouldReceiveTraffic(); + } + } + /** Returns whether this container should receive traffic at this time */ public boolean isInRotation() { - if (inRotationOverride != null) return inRotationOverride; - return clustersStatus.containerShouldReceiveTraffic(); + return currentlyInRotation; } } 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 c8cf575dff3..be62f8177c2 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 @@ -57,7 +57,7 @@ public final class VipStatusHandler extends ThreadedHttpRequestHandler { private StatusResponse() { super(com.yahoo.jdisc.http.HttpResponse.Status.OK); // status may be overwritten below if (vipStatus != null && ! vipStatus.isInRotation()) { - searchContainerOutOfService(); + setOutOfServiceStatus(); } else if (accessDisk) { preSlurpFile(); } else { @@ -140,7 +140,7 @@ public final class VipStatusHandler extends ThreadedHttpRequestHandler { /** * Behaves like a VIP status response file has been deleted. */ - private void searchContainerOutOfService() { + private void setOutOfServiceStatus() { contentType = "text/plain"; data = Utf8.toBytes(NO_SEARCH_BACKENDS); setStatus(com.yahoo.jdisc.http.HttpResponse.Status.NOT_FOUND); @@ -191,8 +191,8 @@ public final class VipStatusHandler extends ThreadedHttpRequestHandler { } private void updateAndLogRotationState() { - final boolean currentlyInRotation = vipStatus.isInRotation(); - final boolean previousRotationAnswer = previouslyInRotation; + boolean currentlyInRotation = vipStatus.isInRotation(); + boolean previousRotationAnswer = previouslyInRotation; previouslyInRotation = currentlyInRotation; if (previousRotationAnswer != currentlyInRotation) { |