summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java1
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java5
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ClientUpdater.java1
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigSourceClient.java2
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponse.java6
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponses.java1
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/MemoryCache.java2
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java2
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java3
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/Subscriber.java1
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/UpstreamConfigSubscriber.java10
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java1
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigHandle.java11
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigSubscriber.java2
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java11
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java1
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/ConfigCacheKey.java4
-rwxr-xr-xconfig/src/main/java/com/yahoo/vespa/config/ConfigKey.java1
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/GetConfigRequest.java7
-rwxr-xr-xconfig/src/main/java/com/yahoo/vespa/config/RawConfig.java13
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/JRTConfigRequest.java15
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/SlimeRequestData.java7
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerDB.java1
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpConfigResponse.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java16
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/SessionCounter.java1
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java8
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java3
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java13
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java3
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/TimeBudget.java55
-rw-r--r--jdisc_core/src/test/java/com/yahoo/jdisc/TimeBudgetTestCase.java29
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorContext.java44
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorImpl.java48
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClient.java6
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientImpl.java21
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerJaxRsApi.java3
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNode.java3
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNodeImpl.java5
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java30
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/Policy.java21
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/InMemoryStatusService.java7
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/StatusService.java5
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/ZookeeperStatusService.java3
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/OrchestratorImplTest.java7
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientFactoryMock.java5
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientTest.java9
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/SingleInstanceClusterControllerClientFactoryTest.java9
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java15
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostResourceTest.java48
54 files changed, 373 insertions, 165 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java
index a3769299cf8..236a954f483 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java
@@ -171,4 +171,5 @@ public class ApplicationMetaData {
throw new RuntimeException("Unable to encode metadata", e);
}
}
+
}
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java
index 111073aca77..2254b6d7747 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java
@@ -11,14 +11,13 @@ import java.util.Optional;
*/
public interface Deployer {
-
/**
* Creates a new deployment from the active application, if available. Will use the default timeout for deployment.
*
* @param application the active application to be redeployed
* @return a new deployment from the local active, or empty if a local active application
- * was not present for this id (meaning it either is not active or active on another
- * node in the config server cluster)
+ * was not present for this id (meaning it either is not active or deployed at another
+ * node in the config server cluster)
*/
Optional<Deployment> deployFromLocalActive(ApplicationId application);
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ClientUpdater.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ClientUpdater.java
index 0ed5d04e36e..8b8f75a3f99 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ClientUpdater.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ClientUpdater.java
@@ -15,6 +15,7 @@ import java.util.logging.Logger;
* @author hmusum
*/
class ClientUpdater {
+
private final static Logger log = Logger.getLogger(ClientUpdater.class.getName());
private final ConfigProxyStatistics statistics;
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigSourceClient.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigSourceClient.java
index f636e723828..5bab27c27a5 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigSourceClient.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigSourceClient.java
@@ -11,7 +11,6 @@ import java.util.List;
* getting config.
*
* @author hmusum
- * @since 5.1.9
*/
interface ConfigSourceClient {
@@ -24,4 +23,5 @@ interface ConfigSourceClient {
String getActiveSourceConnection();
List<String> getSourceConnections();
+
}
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponse.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponse.java
index 76c5cb424e8..047576ee647 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponse.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponse.java
@@ -15,6 +15,7 @@ import java.util.concurrent.TimeUnit;
* @see DelayedResponseHandler
*/
public class DelayedResponse implements Delayed {
+
private final JRTServerConfigRequest request;
private final long returnTime;
@@ -58,8 +59,7 @@ public class DelayedResponse implements Delayed {
@Override
public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(request.getShortDescription()).append(", delayLeft=").append(getDelay(TimeUnit.MILLISECONDS)).append(" ms");
- return sb.toString();
+ return request.getShortDescription() + ", delayLeft=" + getDelay(TimeUnit.MILLISECONDS) + " ms";
}
+
}
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponses.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponses.java
index 00f948ef690..953aeefbfd1 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponses.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/DelayedResponses.java
@@ -7,7 +7,6 @@ import java.util.concurrent.DelayQueue;
* Queue for requests that have no corresponding config in cache and which we are awaiting response from server for
*
* @author hmusum
- * @since 5.1.7
*/
class DelayedResponses {
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/MemoryCache.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/MemoryCache.java
index 7914b7a80b6..0fe7fe01467 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/MemoryCache.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/MemoryCache.java
@@ -21,6 +21,7 @@ import java.util.logging.Logger;
* @author hmusum
*/
public class MemoryCache {
+
private static final Logger log = Logger.getLogger(MemoryCache.class.getName());
// Separator in file names between different fields of config key
@@ -35,6 +36,7 @@ public class MemoryCache {
/**
* Put in cache, except when config has an error
+ *
* @param config config to put in cache
*/
public void put(RawConfig config) {
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java
index 28bcca9db13..6390c9ca165 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java
@@ -132,7 +132,7 @@ public class ProxyServer implements Runnable {
}
static boolean configOrGenerationHasChanged(RawConfig config, JRTServerConfigRequest request) {
- return (config != null && (!config.hasEqualConfig(request) || config.hasNewerGeneration(request)));
+ return (config != null && ( ! config.hasEqualConfig(request) || config.hasNewerGeneration(request)));
}
Mode getMode() {
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java
index 0f80f228b36..b4eda05fde4 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java
@@ -148,7 +148,8 @@ class RpcConfigSourceClient implements ConfigSourceClient {
log.log(LogLevel.DEBUG, () -> "Already a subscriber running for: " + configCacheKey);
} else {
log.log(LogLevel.DEBUG, () -> "Could not find good config in cache, creating subscriber for: " + configCacheKey);
- UpstreamConfigSubscriber subscriber = new UpstreamConfigSubscriber(input, clientUpdater, configSourceSet, timingValues, requesterPool, memoryCache);
+ UpstreamConfigSubscriber subscriber = new UpstreamConfigSubscriber(input, clientUpdater, configSourceSet,
+ timingValues, requesterPool, memoryCache);
try {
subscriber.subscribe();
activeSubscribers.put(configCacheKey, subscriber);
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/Subscriber.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/Subscriber.java
index 32b1c661a75..74c99b7670b 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/Subscriber.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/Subscriber.java
@@ -5,7 +5,6 @@ package com.yahoo.vespa.config.proxy;
* Interface for subscribing to config from upstream config sources.
*
* @author hmusum
- * @since 5.5
*/
public interface Subscriber extends Runnable {
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/UpstreamConfigSubscriber.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/UpstreamConfigSubscriber.java
index 528c61fe132..ceaf57e9cf1 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/UpstreamConfigSubscriber.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/UpstreamConfigSubscriber.java
@@ -17,9 +17,9 @@ import java.util.logging.Logger;
/**
* @author hmusum
- * @since 5.5
*/
public class UpstreamConfigSubscriber implements Subscriber {
+
private final static Logger log = Logger.getLogger(UpstreamConfigSubscriber.class.getName());
private final RawConfig config;
@@ -33,8 +33,7 @@ public class UpstreamConfigSubscriber implements Subscriber {
UpstreamConfigSubscriber(RawConfig config, ClientUpdater clientUpdater, ConfigSource configSourceSet,
TimingValues timingValues, Map<ConfigSourceSet, JRTConfigRequester> requesterPool,
- MemoryCache memoryCache)
- {
+ MemoryCache memoryCache) {
this.config = config;
this.clientUpdater = clientUpdater;
this.configSourceSet = configSourceSet;
@@ -46,7 +45,7 @@ public class UpstreamConfigSubscriber implements Subscriber {
void subscribe() {
subscriber = new GenericConfigSubscriber(requesterPool);
ConfigKey<?> key = config.getKey();
- handle = subscriber.subscribe(new ConfigKey<RawConfig>(key.getName(), key.getConfigId(), key.getNamespace()),
+ handle = subscriber.subscribe(new ConfigKey<>(key.getName(), key.getConfigId(), key.getNamespace()),
config.getDefContent(), configSourceSet, timingValues);
}
@@ -66,7 +65,7 @@ public class UpstreamConfigSubscriber implements Subscriber {
}
private void updateWithNewConfig(GenericConfigHandle handle) {
- final RawConfig newConfig = handle.getRawConfig();
+ RawConfig newConfig = handle.getRawConfig();
if (log.isLoggable(LogLevel.DEBUG)) {
log.log(LogLevel.DEBUG, "config to be returned for '" + newConfig.getKey() +
"', generation=" + newConfig.getGeneration() +
@@ -82,4 +81,5 @@ public class UpstreamConfigSubscriber implements Subscriber {
subscriber.close();
}
}
+
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java
index 9f277330401..64eee39af1f 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java
@@ -324,6 +324,7 @@ public abstract class ConfigSubscription<T extends ConfigInstance> {
* True if someone has set the {@link #reloadedGeneration} number by calling {@link #reload(long)}
* and hence wants to force a given generation programmatically. If that is the case,
* sets the generation and flags it as changed accordingly.
+ *
* @return true if {@link #reload(long)} has been called, false otherwise
*/
protected boolean checkReloaded() {
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigHandle.java b/config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigHandle.java
index 916aa6faeff..bf247dffb7c 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigHandle.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigHandle.java
@@ -12,14 +12,15 @@ import com.yahoo.vespa.config.RawConfig;
@SuppressWarnings({"rawtypes", "unchecked"})
public class GenericConfigHandle extends ConfigHandle {
- private final GenericJRTConfigSubscription genSub;
+ private final GenericJRTConfigSubscription subscription;
- public GenericConfigHandle(GenericJRTConfigSubscription sub) {
- super(sub);
- genSub = sub;
+ public GenericConfigHandle(GenericJRTConfigSubscription subscription) {
+ super(subscription);
+ this.subscription = subscription;
}
public RawConfig getRawConfig() {
- return genSub.getRawConfig();
+ return subscription.getRawConfig();
}
+
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigSubscriber.java b/config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigSubscriber.java
index a33c1556dd3..82d4708f53b 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigSubscriber.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/GenericConfigSubscriber.java
@@ -19,6 +19,7 @@ import com.yahoo.vespa.config.TimingValues;
* @author vegardh
*/
public class GenericConfigSubscriber extends ConfigSubscriber {
+
/**
* Constructs a new subscriber using the given pool of requesters (JRTConfigRequester holds 1 connection which in
* turn is subject to failover across the elems in the source set.)
@@ -72,4 +73,5 @@ public class GenericConfigSubscriber extends ConfigSubscriber {
*/
public void closeRequesters() {
}
+
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java
index e8c7edd3943..c1f9ce02650 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java
@@ -50,6 +50,17 @@ public class GenericJRTConfigSubscription extends JRTConfigSubscription<RawConfi
}
}
+ // Override to propagate internal redeploy into the config value in addition to the config state
+ @Override
+ void setInternalRedeploy(boolean internalRedeploy) {
+ super.setInternalRedeploy(internalRedeploy);
+ ConfigState<RawConfig> configState = getConfigState();
+
+ if (configState.getConfig() != null) {
+ configState.getConfig().setInternalRedeploy(internalRedeploy);
+ }
+ }
+
public RawConfig getRawConfig() {
return getConfigState().getConfig();
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java
index 920c8c264e7..58f720b8cb6 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java
@@ -172,6 +172,7 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc
/**
* The timing values of this
+ *
* @return timing values
*/
public TimingValues timingValues() {
diff --git a/config/src/main/java/com/yahoo/vespa/config/ConfigCacheKey.java b/config/src/main/java/com/yahoo/vespa/config/ConfigCacheKey.java
index 79edeea99fc..e8e3fe9ed94 100644
--- a/config/src/main/java/com/yahoo/vespa/config/ConfigCacheKey.java
+++ b/config/src/main/java/com/yahoo/vespa/config/ConfigCacheKey.java
@@ -3,10 +3,11 @@ package com.yahoo.vespa.config;
/**
* A ConfigKey that also uses the def MD5 sum. Used for caching when def payload is user provided.
- * @author vegardh
*
+ * @author Vegard Havdal
*/
public class ConfigCacheKey {
+
private final ConfigKey<?> key;
private final String defMd5;
@@ -45,6 +46,7 @@ public class ConfigCacheKey {
/**
* The def md5 sum of this key
+ *
* @return md5 sum
*/
public String getDefMd5() {
diff --git a/config/src/main/java/com/yahoo/vespa/config/ConfigKey.java b/config/src/main/java/com/yahoo/vespa/config/ConfigKey.java
index 5f068c4708a..930b74ea804 100755
--- a/config/src/main/java/com/yahoo/vespa/config/ConfigKey.java
+++ b/config/src/main/java/com/yahoo/vespa/config/ConfigKey.java
@@ -135,4 +135,5 @@ public class ConfigKey<CONFIGCLASS extends ConfigInstance> implements Comparable
public static ConfigKey<?> createFull(String name, String configId, String namespace, String md5) {
return new ConfigKey<>(name, configId, namespace, md5, null);
}
+
}
diff --git a/config/src/main/java/com/yahoo/vespa/config/GetConfigRequest.java b/config/src/main/java/com/yahoo/vespa/config/GetConfigRequest.java
index 8021fa95514..c5eeab74157 100644
--- a/config/src/main/java/com/yahoo/vespa/config/GetConfigRequest.java
+++ b/config/src/main/java/com/yahoo/vespa/config/GetConfigRequest.java
@@ -7,10 +7,8 @@ import java.util.Optional;
/**
* Interface for getConfig requests.
- * @author lulf
- * @since 5.3
+ * @author Ulf Lilleengen
*/
-
public interface GetConfigRequest {
/**
@@ -22,6 +20,7 @@ public interface GetConfigRequest {
/**
* The def file contents in the request, or empty array if not sent/not supported
+ *
* @return the contents (payload) of the def schema
*/
DefContent getDefContent();
@@ -33,7 +32,9 @@ public interface GetConfigRequest {
/**
* Whether or not the config can be retrieved from or stored in a cache.
+ *
* @return true if content should _not_ be cached, false if it should.
*/
boolean noCache();
+
}
diff --git a/config/src/main/java/com/yahoo/vespa/config/RawConfig.java b/config/src/main/java/com/yahoo/vespa/config/RawConfig.java
index ae4431e5195..96908f055f1 100755
--- a/config/src/main/java/com/yahoo/vespa/config/RawConfig.java
+++ b/config/src/main/java/com/yahoo/vespa/config/RawConfig.java
@@ -35,6 +35,7 @@ public class RawConfig extends ConfigInstance {
/**
* Constructor for an empty config (not yet resolved).
+ *
* @param key The ConfigKey
* @param defMd5 The md5 sum of the .def-file.
*/
@@ -69,6 +70,7 @@ public class RawConfig extends ConfigInstance {
/**
* Creates a new Config from the given request, with the values in the response parameters.
+ *
* @param req a {@link JRTClientConfigRequest}
*/
public static RawConfig createFromResponseParameters(JRTClientConfigRequest req) {
@@ -85,6 +87,7 @@ public class RawConfig extends ConfigInstance {
/**
* Creates a new Config from the given request, with the values in the response parameters.
+ *
* @param req a {@link JRTClientConfigRequest}
*/
public static RawConfig createFromServerRequest(JRTServerConfigRequest req) {
@@ -116,6 +119,8 @@ public class RawConfig extends ConfigInstance {
public void setGeneration(long generation) { this.generation = generation; }
+ public void setInternalRedeploy(boolean internalRedeploy) { this.internalRedeploy = internalRedeploy; }
+
/**
* Returns whether this config generation was created by a system internal redeploy, not an
* application package change.
@@ -133,7 +138,7 @@ public class RawConfig extends ConfigInstance {
/**
* Returns true if this config is equal to the config (same payload md5) in the given request.
*
- * @param req The request for which to compare config payload with this config.
+ * @param req the request for which to compare config payload with this config.
* @return true if this config is equal to the config in the given request.
*/
public boolean hasEqualConfig(JRTServerConfigRequest req) {
@@ -143,7 +148,7 @@ public class RawConfig extends ConfigInstance {
/**
* Returns true if this config has a more recent generation than the config in the given request.
*
- * @param req The request for which to compare generation with this config.
+ * @param req the request for which to compare generation with this config.
* @return true if this config has a more recent generation than the config in the given request.
*/
public boolean hasNewerGeneration(JRTServerConfigRequest req) {
@@ -158,6 +163,7 @@ public class RawConfig extends ConfigInstance {
return (errorCode() != 0);
}
+ @Override
public boolean equals(Object o) {
if (o == this) {
return true;
@@ -184,6 +190,7 @@ public class RawConfig extends ConfigInstance {
}
}
+ @Override
public int hashCode() {
int hash = 17;
if (key != null) {
@@ -203,6 +210,7 @@ public class RawConfig extends ConfigInstance {
return hash;
}
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(key.getNamespace()).append(".").append(key.getName());
@@ -222,4 +230,5 @@ public class RawConfig extends ConfigInstance {
public List<String> getDefContent() {
return defContent;
}
+
}
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTConfigRequest.java b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTConfigRequest.java
index 46b3651afd7..26fa41c19c7 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTConfigRequest.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTConfigRequest.java
@@ -8,11 +8,14 @@ import java.util.Optional;
/**
* Common interface for jrt config requests available both at server and client.
+ *
* @author Ulf Lilleengen
*/
public interface JRTConfigRequest {
+
/**
* Get the config key of the config request.
+ *
* @return a {@link ConfigKey}.
*/
ConfigKey<?> getConfigKey();
@@ -20,18 +23,21 @@ public interface JRTConfigRequest {
/**
* Perform request parameter validation of this config request. This method should be called before fetching
* any kind of config protocol-specific parameter.
+ *
* @return true if valid, false if not.
*/
boolean validateParameters();
/**
* Get the config md5 of the config request. Return an empty string if no response has been returned.
+ *
* @return a config md5.
*/
String getRequestConfigMd5();
/**
* Get the generation of the requested config. If none has been given, 0 should be returned.
+ *
* @return the generation in the request.
*/
long getRequestGeneration();
@@ -39,42 +45,49 @@ public interface JRTConfigRequest {
/**
* Get the JRT request object for this config request.
* TODO: This method leaks the internal jrt stuff :(
+ *
* @return a {@link Request} object.
*/
Request getRequest();
/**
* Get a short hand description of this request.
+ *
* @return a short description
*/
String getShortDescription();
/**
* Get the error code of this request
+ *
* @return the error code as defined in {@link com.yahoo.vespa.config.ErrorCode}.
*/
int errorCode();
/**
* Return the error message of this request, mostly corresponding to the {@link com.yahoo.vespa.config.ErrorCode}.
+ *
* @return the error message.
*/
String errorMessage();
/**
* Get the server timeout of this request.
+ *
* @return the timeout given to the server
*/
long getTimeout();
/**
* Get the config protocol version
+ *
* @return a protocol version number.
*/
long getProtocolVersion();
/**
* Get the wanted generation for this request.
+ *
* @return a generation that client would like.
*/
long getWantedGeneration();
@@ -87,7 +100,9 @@ public interface JRTConfigRequest {
/**
* Get the Vespa version of the client that initiated the request
+ *
* @return Vespa version of the client
*/
Optional<VespaVersion> getVespaVersion();
+
}
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeRequestData.java b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeRequestData.java
index 65e50acb72d..5e88c4cb146 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeRequestData.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeRequestData.java
@@ -12,11 +12,10 @@ import com.yahoo.vespa.config.ConfigKey;
import java.util.Optional;
/**
- * Contains slime request data objects. Provides methods for reading various fields from slime request data. All
- * data is read lazily.
+ * Contains slime request data objects. Provides methods for reading various fields from slime request data.
+ * All data is read lazily.
*
-* @author lulf
-* @since 5.18
+* @author Ulf Lilleengen
*/
class SlimeRequestData {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerDB.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerDB.java
index 72a470cf937..152fc47d807 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerDB.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ConfigServerDB.java
@@ -20,6 +20,7 @@ import java.util.List;
* @author Ulf Lilleengen
*/
public class ConfigServerDB {
+
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(ConfigServerDB.class.getName());
private final File serverDB;
private final ConfigserverConfig configserverConfig;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java
index 9999fb31e77..d5f3a237b9d 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java
@@ -23,8 +23,7 @@ import java.util.Set;
/**
* Handles request for supermodel config.
*
- * @author lulf
- * @since 5.9
+ * @author Ulf Lilleengen
*/
public class SuperModelRequestHandler implements RequestHandler {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpConfigResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpConfigResponse.java
index 489424f8791..43fc0a2f418 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpConfigResponse.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/HttpConfigResponse.java
@@ -14,9 +14,9 @@ import static com.yahoo.jdisc.http.HttpResponse.Status.OK;
* HTTP getConfig response
*
* @author lulf
- * @since 5.1
*/
public class HttpConfigResponse extends HttpResponse {
+
public static final String JSON_CONTENT_TYPE = "application/json";
private final ConfigResponse config;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java
index 5c5d5f55a4d..b0cb287ed0b 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java
@@ -149,7 +149,7 @@ public abstract class ModelsBuilder<MODELRESULT extends ModelResult> {
// TODO: Enable for all zones
if (Arrays.asList(Environment.dev, Environment.test, Environment.staging).contains(zone().environment())
- || zone().region().value().equals("corp-us-east-1"))
+ || Arrays.asList("corp-us-east-1", "ap-southeast-1").contains(zone().region().value()))
versions = keepThoseUsedOn(allocatedHosts.get(), versions);
// TODO: We use the allocated hosts from the newest version when building older model versions.
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java
index 970fe9f169b..55d5321c93f 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java
@@ -42,7 +42,7 @@ class GetConfigProcessor implements Runnable {
}
private void respond(JRTServerConfigRequest request) {
- final Request req = request.getRequest();
+ Request req = request.getRequest();
if (req.isError()) {
Level logLevel = (req.errorCode() == ErrorCode.APPLICATION_NOT_LOADED) ? LogLevel.DEBUG : LogLevel.INFO;
log.log(logLevel, logPre + req.errorMessage());
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java
index 10590a26690..6e34511c62d 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java
@@ -92,14 +92,14 @@ public class SessionFactoryImpl implements SessionFactory, LocalSessionLoader {
File configApplicationDir,
String applicationName,
long sessionId,
- long currentlyActiveSession,
+ long currentlyActiveSessionId,
boolean internalRedeploy) {
long deployTimestamp = System.currentTimeMillis();
String user = System.getenv("USER");
if (user == null) {
user = "unknown";
}
- DeployData deployData = new DeployData(user, userDir.getAbsolutePath(), applicationName, deployTimestamp, internalRedeploy, sessionId, currentlyActiveSession);
+ DeployData deployData = new DeployData(user, userDir.getAbsolutePath(), applicationName, deployTimestamp, internalRedeploy, sessionId, currentlyActiveSessionId);
return FilesApplicationPackage.fromFileWithDeployData(configApplicationDir, deployData);
}
@@ -128,15 +128,15 @@ public class SessionFactoryImpl implements SessionFactory, LocalSessionLoader {
File existingApp = getSessionAppDir(existingSession.getSessionId());
ApplicationId existingApplicationId = existingSession.getApplicationId();
- long liveApp = getLiveApp(existingApplicationId);
- logger.log(LogLevel.DEBUG, "Create from existing application id " + existingApplicationId + ", live app for it is " + liveApp);
- LocalSession session = create(existingApp, existingApplicationId, liveApp, internalRedeploy, timeoutBudget);
+ long activeSessionId = getActiveSessionId(existingApplicationId);
+ logger.log(LogLevel.DEBUG, "Create from existing application id " + existingApplicationId + ", active session id is " + activeSessionId);
+ LocalSession session = create(existingApp, existingApplicationId, activeSessionId, internalRedeploy, timeoutBudget);
session.setApplicationId(existingApplicationId);
session.setVespaVersion(existingSession.getVespaVersion());
return session;
}
- private LocalSession create(File applicationFile, ApplicationId applicationId, long currentlyActiveSession,
+ private LocalSession create(File applicationFile, ApplicationId applicationId, long currentlyActiveSessionId,
boolean internalRedeploy, TimeoutBudget timeoutBudget) {
long sessionId = sessionCounter.nextSessionId();
Path sessionIdPath = sessionsPath.append(String.valueOf(sessionId));
@@ -155,7 +155,7 @@ public class SessionFactoryImpl implements SessionFactory, LocalSessionLoader {
userApplicationDir,
applicationId.application().value(),
sessionId,
- currentlyActiveSession,
+ currentlyActiveSessionId,
internalRedeploy);
applicationPackage.writeMetaData();
return createSessionFromApplication(applicationPackage, sessionId, sessionZooKeeperClient, timeoutBudget, clock);
@@ -188,7 +188,7 @@ public class SessionFactoryImpl implements SessionFactory, LocalSessionLoader {
return new LocalSession(tenant, sessionId, sessionPreparer, context);
}
- private long getLiveApp(ApplicationId applicationId) {
+ private long getActiveSessionId(ApplicationId applicationId) {
List<ApplicationId> applicationIds = applicationRepo.listApplications();
if (applicationIds.contains(applicationId)) {
return applicationRepo.getSessionIdForApplication(applicationId);
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/SessionCounter.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/SessionCounter.java
index 2a25553d456..17d0f7e426e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/SessionCounter.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/SessionCounter.java
@@ -25,4 +25,5 @@ public class SessionCounter extends InitializedCounter {
public long nextSessionId() {
return counter.next();
}
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java
index 8084be1cefa..0aa6a6c88dc 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKLiveApp.java
@@ -14,7 +14,10 @@ import java.util.logging.Logger;
/**
* Responsible for providing data from the currently live application subtree in zookeeper.
- * (i.e. /vespa/config/apps/&lt;id of currently active app&gt;/)
+ * (i.e. /vespa/config/apps/&lt;id of currently active app&gt;/).
+ *
+ * Note: The application revision ("session") stored in this tree is not necessarily live, just complete,
+ * preparable, prepared or active.
*
* @author tonytv
*/
@@ -34,7 +37,8 @@ public class ZKLiveApp {
* Returns a list of the files (as readers) in the given path. The readers <b>must</b>
* be closed by the caller.
*
- * @param path a path relative to the currently active application (i.e. /vespa/config/apps/&lt;id of currently active app&gt;/).
+ * @param path a path relative to the currently active application
+ * (i.e. /vespa/config/apps/&lt;id of currently active app&gt;/).
* @param fileNameSuffix the suffix of files to return, or null to return all
* @param recursive if true, all files from all subdirectories of this will also be returned
* @return the files in the given path, or an empty list (never null) if the directory does not exist or is empty.
diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
index b1399c6cc8d..0d9534457e9 100644
--- a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
@@ -192,8 +192,7 @@ public class ClusterSearcher extends Searcher {
private static ClusterParams makeClusterParams(int searchclusterIndex,
LegacyEmulationConfig emulConfig,
int dispatchIndex) {
- return new ClusterParams(searchclusterIndex,
- "sc" + searchclusterIndex + ".num" + dispatchIndex,
+ return new ClusterParams("sc" + searchclusterIndex + ".num" + dispatchIndex,
emulConfig);
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
index f95f303e87c..3dfa506a967 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
@@ -11,29 +11,20 @@ import com.yahoo.container.search.LegacyEmulationConfig;
*/
public class ClusterParams {
- public final int clusterNumber;
public final String searcherName;
public final LegacyEmulationConfig emulation;
/**
- * For compatibility
- */
- public ClusterParams(int number, String name) {
- this(number, name, new LegacyEmulationConfig(new LegacyEmulationConfig.Builder()));
- }
-
- /**
* For testcases only
*/
public ClusterParams(String name) {
- this(0, name);
+ this(name, new LegacyEmulationConfig(new LegacyEmulationConfig.Builder()));
}
/**
* Make up full ClusterParams
*/
- public ClusterParams(int number, String name, LegacyEmulationConfig cfg) {
- this.clusterNumber = number;
+ public ClusterParams(String name, LegacyEmulationConfig cfg) {
this.searcherName = name;
this.emulation = cfg;
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java
index 3abd97d814e..34e8390892d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java
@@ -75,9 +75,6 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
/** Cache wrapper */
protected CacheControl cacheControl = null;
- /** Searchcluster number */
- private int sourceNumber;
-
protected final String getName() { return name; }
protected final String getDefaultDocsumClass() { return defaultDocsumClass; }
@@ -168,7 +165,6 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
public final void init(SummaryParameters docSumParams, ClusterParams clusterParams, CacheParams cacheParams,
DocumentdbInfoConfig documentdbInfoConfig) {
this.name = clusterParams.searcherName;
- this.sourceNumber = clusterParams.clusterNumber;
Validator.ensureNotNull("Name of Vespa backend integration", getName());
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index d6c0bf23da6..4b09e78ede2 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -688,7 +688,8 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
ApplicationId id = ApplicationId.from(tenantName, applicationName, "default");
controller.applications().lockOrThrow(id, application -> {
- controller.applications().deploymentTrigger().triggerChange(application.get().id(), Change.of(version));
+ controller.applications().deploymentTrigger().triggerChange(application.get().id(),
+ application.get().change().with(version));
});
return new MessageResponse("Triggered deployment of application '" + id + "' on version " + version);
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/TimeBudget.java b/jdisc_core/src/main/java/com/yahoo/jdisc/TimeBudget.java
new file mode 100644
index 00000000000..39322b6e83a
--- /dev/null
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/TimeBudget.java
@@ -0,0 +1,55 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc;
+
+import javax.annotation.concurrent.Immutable;
+import java.time.Duration;
+import java.time.Instant;
+
+/**
+ * A TimeBudget tracks the current time compared to a start time and deadline.
+ *
+ * @author hakon
+ */
+@Immutable
+public class TimeBudget {
+ private final Timer timer;
+ private final Instant start;
+ private final Duration timeout;
+
+ /** Returns a TimeBudget with a start time of now, and with the given timeout. */
+ public static TimeBudget fromNow(Timer timer, Duration timeout) {
+ return new TimeBudget(timer, timer.currentTime(), timeout);
+ }
+
+ private TimeBudget(Timer timer, Instant start, Duration timeout) {
+ this.timer = timer;
+ this.start = start;
+ this.timeout = timeout;
+ }
+
+ /** Time until 'headroom' before deadline. Guaranteed to be non-negative. */
+ public Duration timeBeforeDeadline(Duration headroom) {
+ return nonNegativeBetween(now(), deadline().minus(headroom));
+ }
+
+ /** Returns the original timeout. */
+ public Duration originalTimeout() {
+ return timeout;
+ }
+
+ private static Duration nonNegativeBetween(Instant start, Instant end) {
+ return makeNonNegative(Duration.between(start, end));
+ }
+
+ private static Duration makeNonNegative(Duration duration) {
+ return duration.isNegative() ? Duration.ZERO : duration;
+ }
+
+ private Instant now() {
+ return timer.currentTime();
+ }
+
+ private Instant deadline() {
+ return start.plus(timeout);
+ }
+}
diff --git a/jdisc_core/src/test/java/com/yahoo/jdisc/TimeBudgetTestCase.java b/jdisc_core/src/test/java/com/yahoo/jdisc/TimeBudgetTestCase.java
new file mode 100644
index 00000000000..5afc205beb3
--- /dev/null
+++ b/jdisc_core/src/test/java/com/yahoo/jdisc/TimeBudgetTestCase.java
@@ -0,0 +1,29 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.jdisc;
+
+import org.junit.Test;
+
+import java.time.Duration;
+import java.time.Instant;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class TimeBudgetTestCase {
+ private final Timer timer = mock(Timer.class);
+
+ @Test
+ public void testBasics() {
+ when(timer.currentTime()).thenReturn(Instant.ofEpochSecond(0));
+ TimeBudget timeBudget = TimeBudget.fromNow(timer, Duration.ofSeconds(10));
+
+ when(timer.currentTime()).thenReturn(Instant.ofEpochSecond(7));
+ assertEquals(Duration.ofSeconds(3), timeBudget.timeBeforeDeadline(Duration.ofSeconds(0)));
+ assertEquals(Duration.ofSeconds(1), timeBudget.timeBeforeDeadline(Duration.ofSeconds(2)));
+ assertEquals(Duration.ofSeconds(0), timeBudget.timeBeforeDeadline(Duration.ofSeconds(5)));
+
+ when(timer.currentTime()).thenReturn(Instant.ofEpochSecond(11));
+ assertEquals(Duration.ofSeconds(0), timeBudget.timeBeforeDeadline(Duration.ofSeconds(0)));
+ }
+} \ No newline at end of file
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorContext.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorContext.java
new file mode 100644
index 00000000000..9e605561e7b
--- /dev/null
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorContext.java
@@ -0,0 +1,44 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator;
+
+import com.yahoo.jdisc.TimeBudget;
+import com.yahoo.jdisc.Timer;
+
+import java.time.Duration;
+import java.util.Optional;
+
+/**
+ * Context for the Orchestrator, e.g. timeout management.
+ *
+ * @author hakon
+ */
+public class OrchestratorContext {
+ private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10);
+ private static final Duration POST_OPERATION_HEADROOM = Duration.ofMillis(100);
+
+ private TimeBudget timeBudget;
+
+ public OrchestratorContext(Timer timer) {
+ this.timeBudget = TimeBudget.fromNow(timer, DEFAULT_TIMEOUT);
+ }
+
+ /** Get the original timeout in seconds. */
+ public long getOriginalTimeoutInSeconds() {
+ return timeBudget.originalTimeout().getSeconds();
+ }
+
+ /**
+ * Get number of seconds until the deadline, or empty if there's no deadline.
+ *
+ * <p>The returned timeout is slightly shorter than the actual timeout to ensure there's
+ * enough time to wrap up and return from the Orchestrator between when the operation
+ * times out and the actual timeout.
+ */
+ public Optional<Float> getSuboperationTimeoutInSeconds() {
+ return getSuboperationTimeoutInSeconds(POST_OPERATION_HEADROOM);
+ }
+
+ private Optional<Float> getSuboperationTimeoutInSeconds(Duration headroom) {
+ return Optional.of((float) (timeBudget.timeBeforeDeadline(headroom).toMillis() / 1000.0));
+ }
+}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorImpl.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorImpl.java
index 095a7da8322..580d34eccf8 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorImpl.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/OrchestratorImpl.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.orchestrator;
import com.google.inject.Inject;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.jdisc.Timer;
import com.yahoo.log.LogLevel;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
@@ -43,7 +44,6 @@ import java.util.stream.Collectors;
* @author smorgrav
*/
public class OrchestratorImpl implements Orchestrator {
-
private static final Logger log = Logger.getLogger(OrchestratorImpl.class.getName());
private final Policy policy;
@@ -51,32 +51,36 @@ public class OrchestratorImpl implements Orchestrator {
private final InstanceLookupService instanceLookupService;
private final int serviceMonitorConvergenceLatencySeconds;
private final ClusterControllerClientFactory clusterControllerClientFactory;
+ private final Timer timer;
@Inject
public OrchestratorImpl(ClusterControllerClientFactory clusterControllerClientFactory,
StatusService statusService,
OrchestratorConfig orchestratorConfig,
- InstanceLookupService instanceLookupService)
+ InstanceLookupService instanceLookupService,
+ Timer timer)
{
this(new HostedVespaPolicy(new HostedVespaClusterPolicy(), clusterControllerClientFactory),
clusterControllerClientFactory,
statusService,
instanceLookupService,
- orchestratorConfig.serviceMonitorConvergenceLatencySeconds());
+ orchestratorConfig.serviceMonitorConvergenceLatencySeconds(),
+ timer);
}
public OrchestratorImpl(Policy policy,
ClusterControllerClientFactory clusterControllerClientFactory,
StatusService statusService,
InstanceLookupService instanceLookupService,
- int serviceMonitorConvergenceLatencySeconds)
+ int serviceMonitorConvergenceLatencySeconds,
+ Timer timer)
{
this.policy = policy;
this.clusterControllerClientFactory = clusterControllerClientFactory;
this.statusService = statusService;
this.serviceMonitorConvergenceLatencySeconds = serviceMonitorConvergenceLatencySeconds;
this.instanceLookupService = instanceLookupService;
-
+ this.timer = timer;
}
@Override
@@ -123,7 +127,10 @@ public class OrchestratorImpl implements Orchestrator {
ApplicationInstance appInstance = getApplicationInstance(hostName);
- try (MutableStatusRegistry statusRegistry = statusService.lockApplicationInstance_forCurrentThreadOnly(appInstance.reference())) {
+ OrchestratorContext context = new OrchestratorContext(timer);
+ try (MutableStatusRegistry statusRegistry = statusService.lockApplicationInstance_forCurrentThreadOnly(
+ appInstance.reference(),
+ context.getOriginalTimeoutInSeconds())) {
final HostStatus currentHostState = statusRegistry.getHostStatus(hostName);
if (HostStatus.NO_REMARKS == currentHostState) {
@@ -132,7 +139,7 @@ public class OrchestratorImpl implements Orchestrator {
ApplicationInstanceStatus appStatus = statusService.forApplicationInstance(appInstance.reference()).getApplicationInstanceStatus();
if (appStatus == ApplicationInstanceStatus.NO_REMARKS) {
- policy.releaseSuspensionGrant(appInstance, hostName, statusRegistry);
+ policy.releaseSuspensionGrant(context, appInstance, hostName, statusRegistry);
}
}
}
@@ -149,13 +156,16 @@ public class OrchestratorImpl implements Orchestrator {
ApplicationInstance appInstance = getApplicationInstance(hostName);
NodeGroup nodeGroup = new NodeGroup(appInstance, hostName);
- try (MutableStatusRegistry statusRegistry = statusService.lockApplicationInstance_forCurrentThreadOnly(appInstance.reference())) {
+ OrchestratorContext context = new OrchestratorContext(timer);
+ try (MutableStatusRegistry statusRegistry = statusService.lockApplicationInstance_forCurrentThreadOnly(
+ appInstance.reference(),
+ context.getOriginalTimeoutInSeconds())) {
ApplicationApi applicationApi = new ApplicationApiImpl(
nodeGroup,
statusRegistry,
clusterControllerClientFactory);
- policy.acquirePermissionToRemove(applicationApi);
+ policy.acquirePermissionToRemove(context, applicationApi);
}
}
@@ -164,7 +174,11 @@ public class OrchestratorImpl implements Orchestrator {
public void suspendGroup(NodeGroup nodeGroup) throws HostStateChangeDeniedException, HostNameNotFoundException {
ApplicationInstanceReference applicationReference = nodeGroup.getApplicationReference();
- try (MutableStatusRegistry hostStatusRegistry = statusService.lockApplicationInstance_forCurrentThreadOnly(applicationReference)) {
+ OrchestratorContext context = new OrchestratorContext(timer);
+ try (MutableStatusRegistry hostStatusRegistry =
+ statusService.lockApplicationInstance_forCurrentThreadOnly(
+ applicationReference,
+ context.getOriginalTimeoutInSeconds())) {
ApplicationInstanceStatus appStatus = statusService.forApplicationInstance(applicationReference).getApplicationInstanceStatus();
if (appStatus == ApplicationInstanceStatus.ALLOWED_TO_BE_DOWN) {
return;
@@ -174,7 +188,7 @@ public class OrchestratorImpl implements Orchestrator {
nodeGroup,
hostStatusRegistry,
clusterControllerClientFactory);
- policy.grantSuspensionRequest(applicationApi);
+ policy.grantSuspensionRequest(context, applicationApi);
}
}
@@ -287,9 +301,12 @@ public class OrchestratorImpl implements Orchestrator {
private void setApplicationStatus(ApplicationId appId, ApplicationInstanceStatus status)
throws ApplicationStateChangeDeniedException, ApplicationIdNotFoundException{
+ OrchestratorContext context = new OrchestratorContext(timer);
ApplicationInstanceReference appRef = OrchestratorUtil.toApplicationInstanceReference(appId, instanceLookupService);
try (MutableStatusRegistry statusRegistry =
- statusService.lockApplicationInstance_forCurrentThreadOnly(appRef)) {
+ statusService.lockApplicationInstance_forCurrentThreadOnly(
+ appRef,
+ context.getOriginalTimeoutInSeconds())) {
// Short-circuit if already in wanted state
if (status == statusRegistry.getApplicationInstanceStatus()) return;
@@ -304,14 +321,15 @@ public class OrchestratorImpl implements Orchestrator {
// If the clustercontroller throws an error the nodes will be marked as allowed to be down
// and be set back up on next resume invocation.
- setClusterStateInController(application, ClusterControllerNodeState.MAINTENANCE);
+ setClusterStateInController(context, application, ClusterControllerNodeState.MAINTENANCE);
}
statusRegistry.setApplicationInstanceStatus(status);
}
}
- private void setClusterStateInController(ApplicationInstance application,
+ private void setClusterStateInController(OrchestratorContext context,
+ ApplicationInstance application,
ClusterControllerNodeState state)
throws ApplicationStateChangeDeniedException, ApplicationIdNotFoundException {
// Get all content clusters for this application
@@ -329,7 +347,7 @@ public class OrchestratorImpl implements Orchestrator {
clusterControllers,
clusterId.s());
try {
- ClusterControllerStateResponse response = client.setApplicationState(state);
+ ClusterControllerStateResponse response = client.setApplicationState(context, state);
if (!response.wasModified) {
String msg = String.format("Fail to set application %s, cluster name %s to cluster state %s due to: %s",
application.applicationInstanceId(), clusterId, state, response.reason);
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClient.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClient.java
index 38cabd5d86d..c2559bdd0da 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClient.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClient.java
@@ -1,6 +1,8 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.orchestrator.controller;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
+
import java.io.IOException;
/**
@@ -13,13 +15,13 @@ public interface ClusterControllerClient {
*
* @throws IOException if there was a problem communicating with the cluster controller
*/
- ClusterControllerStateResponse setNodeState(int storageNodeIndex, ClusterControllerNodeState wantedState) throws IOException;
+ ClusterControllerStateResponse setNodeState(OrchestratorContext context, int storageNodeIndex, ClusterControllerNodeState wantedState) throws IOException;
/**
* Requests that a cluster controller sets all nodes in the cluster to the requested state.
*
* @throws IOException if there was a problem communicating with the cluster controller
*/
- ClusterControllerStateResponse setApplicationState(ClusterControllerNodeState wantedState) throws IOException;
+ ClusterControllerStateResponse setApplicationState(OrchestratorContext context, ClusterControllerNodeState wantedState) throws IOException;
}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientImpl.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientImpl.java
index b70e1a56aea..7d7a9b36ff9 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientImpl.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientImpl.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.orchestrator.controller;
import com.yahoo.vespa.jaxrs.client.JaxRsStrategy;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import java.io.IOException;
@@ -29,12 +30,19 @@ public class ClusterControllerClientImpl implements ClusterControllerClient{
* @throws IOException if there was a problem communicating with the cluster controller
*/
@Override
- public ClusterControllerStateResponse setNodeState(int storageNodeIndex, ClusterControllerNodeState wantedState) throws IOException {
+ public ClusterControllerStateResponse setNodeState(OrchestratorContext context,
+ int storageNodeIndex,
+ ClusterControllerNodeState wantedState) throws IOException {
ClusterControllerStateRequest.State state = new ClusterControllerStateRequest.State(wantedState, REQUEST_REASON);
ClusterControllerStateRequest stateRequest = new ClusterControllerStateRequest(state, ClusterControllerStateRequest.Condition.SAFE);
try {
- return clusterControllerApi.apply(api -> api.setNodeState(clusterName, storageNodeIndex, stateRequest));
+ return clusterControllerApi.apply(api -> api.setNodeState(
+ clusterName,
+ storageNodeIndex,
+ context.getSuboperationTimeoutInSeconds().orElse(null),
+ stateRequest)
+ );
} catch (IOException e) {
String message = String.format(
"Giving up setting %s for storage node with index %d in cluster %s",
@@ -52,12 +60,17 @@ public class ClusterControllerClientImpl implements ClusterControllerClient{
* @throws IOException if there was a problem communicating with the cluster controller
*/
@Override
- public ClusterControllerStateResponse setApplicationState(final ClusterControllerNodeState wantedState) throws IOException {
+ public ClusterControllerStateResponse setApplicationState(
+ OrchestratorContext context,
+ final ClusterControllerNodeState wantedState) throws IOException {
final ClusterControllerStateRequest.State state = new ClusterControllerStateRequest.State(wantedState, REQUEST_REASON);
final ClusterControllerStateRequest stateRequest = new ClusterControllerStateRequest(state, ClusterControllerStateRequest.Condition.FORCE);
try {
- return clusterControllerApi.apply(api -> api.setClusterState(clusterName, stateRequest));
+ return clusterControllerApi.apply(api -> api.setClusterState(
+ clusterName,
+ context.getSuboperationTimeoutInSeconds().orElse(null),
+ stateRequest));
} catch (IOException e) {
final String message = String.format(
"Giving up setting %s for cluster %s",
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerJaxRsApi.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerJaxRsApi.java
index 7059706c569..4831f4c121a 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerJaxRsApi.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerJaxRsApi.java
@@ -6,6 +6,7 @@ import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
/**
@@ -20,6 +21,7 @@ public interface ClusterControllerJaxRsApi {
ClusterControllerStateResponse setNodeState(
@PathParam("clusterName") String clusterName,
@PathParam("storageNodeIndex") int storageNodeIndex,
+ @QueryParam("timeout") Float timeoutSeconds,
ClusterControllerStateRequest request);
@POST
@@ -28,6 +30,7 @@ public interface ClusterControllerJaxRsApi {
@Produces(MediaType.APPLICATION_JSON)
ClusterControllerStateResponse setClusterState(
@PathParam("clusterName") String clusterName,
+ @QueryParam("timeout") Float timeoutSeconds,
ClusterControllerStateRequest request);
}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNode.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNode.java
index 210f68e8fda..a54d829a029 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNode.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNode.java
@@ -2,10 +2,11 @@
package com.yahoo.vespa.orchestrator.model;
import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerNodeState;
import com.yahoo.vespa.orchestrator.policy.HostStateChangeDeniedException;
public interface StorageNode extends Comparable<StorageNode> {
HostName hostName();
- void setNodeState(ClusterControllerNodeState wantedState) throws HostStateChangeDeniedException;
+ void setNodeState(OrchestratorContext context, ClusterControllerNodeState wantedState) throws HostStateChangeDeniedException;
}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNodeImpl.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNodeImpl.java
index 109acbc6486..a2732bca88a 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNodeImpl.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/model/StorageNodeImpl.java
@@ -7,6 +7,7 @@ import com.yahoo.vespa.applicationmodel.ClusterId;
import com.yahoo.vespa.applicationmodel.ConfigId;
import com.yahoo.vespa.applicationmodel.HostName;
import com.yahoo.vespa.applicationmodel.ServiceInstance;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerClient;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerClientFactory;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerNodeState;
@@ -43,7 +44,7 @@ public class StorageNodeImpl implements StorageNode {
}
@Override
- public void setNodeState(ClusterControllerNodeState wantedNodeState)
+ public void setNodeState(OrchestratorContext context, ClusterControllerNodeState wantedNodeState)
throws HostStateChangeDeniedException {
// The "cluster name" used by the Cluster Controller IS the cluster ID.
String clusterId = this.clusterId.s();
@@ -66,7 +67,7 @@ public class StorageNodeImpl implements StorageNode {
ClusterControllerStateResponse response;
try {
- response = client.setNodeState(nodeIndex, wantedNodeState);
+ response = client.setNodeState(context, nodeIndex, wantedNodeState);
} catch (IOException e) {
throw new HostStateChangeDeniedException(
hostName(),
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java
index 8e02f940127..e1664466283 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicy.java
@@ -1,10 +1,10 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.orchestrator.policy;
-import com.yahoo.config.provision.ApplicationId;
import com.yahoo.log.LogLevel;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerClientFactory;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerNodeState;
import com.yahoo.vespa.orchestrator.model.ApplicationApi;
@@ -40,7 +40,7 @@ public class HostedVespaPolicy implements Policy {
}
@Override
- public void grantSuspensionRequest(ApplicationApi application)
+ public void grantSuspensionRequest(OrchestratorContext context, ApplicationApi application)
throws HostStateChangeDeniedException {
// Apply per-cluster policy
for (ClusterApi cluster : application.getClusters()) {
@@ -50,7 +50,7 @@ public class HostedVespaPolicy implements Policy {
// Ask Cluster Controller to set UP storage nodes in maintenance.
// These storage nodes are guaranteed to be NO_REMARKS
for (StorageNode storageNode : application.getUpStorageNodesInGroupInClusterOrder()) {
- storageNode.setNodeState(ClusterControllerNodeState.MAINTENANCE);
+ storageNode.setNodeState(context, ClusterControllerNodeState.MAINTENANCE);
log.log(LogLevel.INFO, "The storage node on " + storageNode.hostName() + " has been set to MAINTENANCE");
}
@@ -62,10 +62,11 @@ public class HostedVespaPolicy implements Policy {
}
@Override
- public void releaseSuspensionGrant(ApplicationApi application) throws HostStateChangeDeniedException {
+ public void releaseSuspensionGrant(OrchestratorContext context, ApplicationApi application)
+ throws HostStateChangeDeniedException {
// Always defer to Cluster Controller whether it's OK to resume storage node
for (StorageNode storageNode : application.getStorageNodesAllowedToBeDownInGroupInReverseClusterOrder()) {
- storageNode.setNodeState(ClusterControllerNodeState.UP);
+ storageNode.setNodeState(context, ClusterControllerNodeState.UP);
log.log(LogLevel.INFO, "The storage node on " + storageNode.hostName() + " has been set to UP");
}
@@ -76,7 +77,8 @@ public class HostedVespaPolicy implements Policy {
}
@Override
- public void acquirePermissionToRemove(ApplicationApi applicationApi) throws HostStateChangeDeniedException {
+ public void acquirePermissionToRemove(OrchestratorContext context, ApplicationApi applicationApi)
+ throws HostStateChangeDeniedException {
ApplicationInstanceStatus applicationStatus = applicationApi.getApplicationStatus();
if (applicationStatus == ApplicationInstanceStatus.ALLOWED_TO_BE_DOWN) {
throw new HostStateChangeDeniedException(
@@ -94,7 +96,7 @@ public class HostedVespaPolicy implements Policy {
// Ask Cluster Controller to set storage nodes to DOWN.
// These storage nodes are guaranteed to be NO_REMARKS
for (StorageNode storageNode : applicationApi.getStorageNodesInGroupInClusterOrder()) {
- storageNode.setNodeState(ClusterControllerNodeState.DOWN);
+ storageNode.setNodeState(context, ClusterControllerNodeState.DOWN);
log.log(LogLevel.INFO, "The storage node on " + storageNode.hostName() + " has been set DOWN");
}
@@ -107,24 +109,14 @@ public class HostedVespaPolicy implements Policy {
// TODO: Remove later - currently used for backward compatibility testing
@Override
- public void grantSuspensionRequest(ApplicationInstance applicationInstance,
- HostName hostName,
- MutableStatusRegistry hostStatusService) throws HostStateChangeDeniedException {
- NodeGroup nodeGroup = new NodeGroup(applicationInstance);
- nodeGroup.addNode(hostName);
- ApplicationApi applicationApi = new ApplicationApiImpl(nodeGroup, hostStatusService, clusterControllerClientFactory);
- grantSuspensionRequest(applicationApi);
- }
-
- // TODO: Remove later - currently used for backward compatibility testing
- @Override
public void releaseSuspensionGrant(
+ OrchestratorContext context,
ApplicationInstance applicationInstance,
HostName hostName,
MutableStatusRegistry hostStatusService) throws HostStateChangeDeniedException {
NodeGroup nodeGroup = new NodeGroup(applicationInstance, hostName);
ApplicationApi applicationApi = new ApplicationApiImpl(nodeGroup, hostStatusService, clusterControllerClientFactory);
- releaseSuspensionGrant(applicationApi);
+ releaseSuspensionGrant(context, applicationApi);
}
}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/Policy.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/Policy.java
index 4ea4f81182f..9938d244657 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/Policy.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/policy/Policy.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.orchestrator.policy;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import com.yahoo.vespa.orchestrator.model.ApplicationApi;
import com.yahoo.vespa.orchestrator.status.MutableStatusRegistry;
@@ -10,30 +11,20 @@ import com.yahoo.vespa.orchestrator.status.MutableStatusRegistry;
* @author oyving
*/
public interface Policy {
-
- /**
- * Decide whether to grant a request for temporarily suspending the services on a host.
- *
- * @throws HostStateChangeDeniedException if the grant was not given.
- */
- void grantSuspensionRequest(
- ApplicationInstance applicationInstance,
- HostName hostName,
- MutableStatusRegistry hostStatusService) throws HostStateChangeDeniedException;
-
/**
* Decide whether to grant a request for temporarily suspending the services on all hosts in the group.
*/
- void grantSuspensionRequest(ApplicationApi applicationApi) throws HostStateChangeDeniedException;
+ void grantSuspensionRequest(OrchestratorContext context, ApplicationApi applicationApi) throws HostStateChangeDeniedException;
- void releaseSuspensionGrant(ApplicationApi application) throws HostStateChangeDeniedException;
+ void releaseSuspensionGrant(OrchestratorContext context, ApplicationApi application) throws HostStateChangeDeniedException;
/**
* Give all hosts in a group permission to be removed from the application.
*
+ * @param context
* @param applicationApi
*/
- void acquirePermissionToRemove(ApplicationApi applicationApi) throws HostStateChangeDeniedException;
+ void acquirePermissionToRemove(OrchestratorContext context, ApplicationApi applicationApi) throws HostStateChangeDeniedException;
/**
* Release an earlier grant for suspension.
@@ -41,7 +32,7 @@ public interface Policy {
* @throws HostStateChangeDeniedException if the release failed.
*/
void releaseSuspensionGrant(
- ApplicationInstance applicationInstance,
+ OrchestratorContext context, ApplicationInstance applicationInstance,
HostName hostName,
MutableStatusRegistry hostStatusService) throws HostStateChangeDeniedException;
}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/InMemoryStatusService.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/InMemoryStatusService.java
index cab14a2e77f..c5ae553a98c 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/InMemoryStatusService.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/InMemoryStatusService.java
@@ -44,6 +44,13 @@ public class InMemoryStatusService implements StatusService {
@Override
public MutableStatusRegistry lockApplicationInstance_forCurrentThreadOnly(ApplicationInstanceReference applicationInstanceReference) {
+ return lockApplicationInstance_forCurrentThreadOnly(applicationInstanceReference, 10);
+ }
+
+ @Override
+ public MutableStatusRegistry lockApplicationInstance_forCurrentThreadOnly(
+ ApplicationInstanceReference applicationInstanceReference,
+ long timeoutSeconds) {
Lock lock = instanceLockService.get(applicationInstanceReference);
return new InMemoryMutableStatusRegistry(lock, applicationInstanceReference);
}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/StatusService.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/StatusService.java
index cf7b40ce0ef..db58544df55 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/StatusService.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/StatusService.java
@@ -54,6 +54,11 @@ public interface StatusService {
*/
MutableStatusRegistry lockApplicationInstance_forCurrentThreadOnly(ApplicationInstanceReference applicationInstanceReference);
+ /** Lock application instance with timeout. */
+ MutableStatusRegistry lockApplicationInstance_forCurrentThreadOnly(
+ ApplicationInstanceReference applicationInstanceReference,
+ long timeoutSeconds);
+
/**
* Returns all application instances that are allowed to be down. The intention is to use this
* for visualization, informational and debugging purposes.
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/ZookeeperStatusService.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/ZookeeperStatusService.java
index c84473a5199..18d6ed4b3f2 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/ZookeeperStatusService.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/status/ZookeeperStatusService.java
@@ -93,7 +93,8 @@ public class ZookeeperStatusService implements StatusService {
}
}
- MutableStatusRegistry lockApplicationInstance_forCurrentThreadOnly(
+ @Override
+ public MutableStatusRegistry lockApplicationInstance_forCurrentThreadOnly(
ApplicationInstanceReference applicationInstanceReference,
long timeoutSeconds) {
String lockPath = applicationInstanceLock2Path(applicationInstanceReference);
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/OrchestratorImplTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/OrchestratorImplTest.java
index 76d9398c44e..c3b1ceb66ec 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/OrchestratorImplTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/OrchestratorImplTest.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.orchestrator;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.jdisc.Timer;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
import com.yahoo.vespa.applicationmodel.ApplicationInstanceId;
import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
@@ -77,7 +78,8 @@ public class OrchestratorImplTest {
clustercontroller,
new InMemoryStatusService(),
new OrchestratorConfig(new OrchestratorConfig.Builder()),
- new DummyInstanceLookupService());
+ new DummyInstanceLookupService(),
+ mock(Timer.class));
clustercontroller.setAllDummyNodesAsUp();
}
@@ -307,7 +309,8 @@ public class OrchestratorImplTest {
clusterControllerClientFactory,
statusService,
new OrchestratorConfig(new OrchestratorConfig.Builder()),
- lookupService);
+ lookupService,
+ mock(Timer.class));
HostName hostName = new HostName("host.yahoo.com");
TenantId tenantId = new TenantId("tenant");
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientFactoryMock.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientFactoryMock.java
index 230e36469d3..5c5ee7d2260 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientFactoryMock.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientFactoryMock.java
@@ -5,6 +5,7 @@ import com.yahoo.vespa.applicationmodel.ApplicationInstance;
import com.yahoo.vespa.applicationmodel.ClusterId;
import com.yahoo.vespa.applicationmodel.HostName;
import com.yahoo.vespa.orchestrator.DummyInstanceLookupService;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import com.yahoo.vespa.orchestrator.model.VespaModelUtil;
import java.io.IOException;
@@ -52,13 +53,13 @@ public class ClusterControllerClientFactoryMock implements ClusterControllerClie
return new ClusterControllerClient() {
@Override
- public ClusterControllerStateResponse setNodeState(int storageNodeIndex, ClusterControllerNodeState wantedState) throws IOException {
+ public ClusterControllerStateResponse setNodeState(OrchestratorContext context, int storageNodeIndex, ClusterControllerNodeState wantedState) throws IOException {
nodes.put(clusterName + storageNodeIndex, wantedState);
return new ClusterControllerStateResponse(true, "Yes");
}
@Override
- public ClusterControllerStateResponse setApplicationState(ClusterControllerNodeState wantedState) throws IOException {
+ public ClusterControllerStateResponse setApplicationState(OrchestratorContext context, ClusterControllerNodeState wantedState) throws IOException {
Set<String> keyCopy = new HashSet<>(nodes.keySet());
for (String s : keyCopy) {
if (s.startsWith(clusterName)) {
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientTest.java
index 09d52326eb8..b3f80b5129f 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/ClusterControllerClientTest.java
@@ -3,12 +3,16 @@ package com.yahoo.vespa.orchestrator.controller;
import com.yahoo.vespa.jaxrs.client.JaxRsStrategy;
import com.yahoo.vespa.jaxrs.client.LocalPassThroughJaxRsStrategy;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import org.junit.Test;
+import java.util.Optional;
+
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class ClusterControllerClientTest {
private static final String CLUSTER_NAME = "clusterName";
@@ -24,7 +28,9 @@ public class ClusterControllerClientTest {
final ClusterControllerNodeState wantedState = ClusterControllerNodeState.MAINTENANCE;
- clusterControllerClient.setNodeState(STORAGE_NODE_INDEX, wantedState);
+ OrchestratorContext context = mock(OrchestratorContext.class);
+ when(context.getSuboperationTimeoutInSeconds()).thenReturn(Optional.of(1.0f));
+ clusterControllerClient.setNodeState(context, STORAGE_NODE_INDEX, wantedState);
final ClusterControllerStateRequest expectedNodeStateRequest = new ClusterControllerStateRequest(
new ClusterControllerStateRequest.State(wantedState, ClusterControllerClientImpl.REQUEST_REASON),
@@ -33,6 +39,7 @@ public class ClusterControllerClientTest {
.setNodeState(
eq(CLUSTER_NAME),
eq(STORAGE_NODE_INDEX),
+ eq(1.0f),
eq(expectedNodeStateRequest));
}
}
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/SingleInstanceClusterControllerClientFactoryTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/SingleInstanceClusterControllerClientFactoryTest.java
index b26d11a113f..c3dbe5c8a92 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/SingleInstanceClusterControllerClientFactoryTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/controller/SingleInstanceClusterControllerClientFactoryTest.java
@@ -4,11 +4,13 @@ package com.yahoo.vespa.orchestrator.controller;
import com.yahoo.vespa.applicationmodel.ConfigId;
import com.yahoo.vespa.applicationmodel.HostName;
import com.yahoo.vespa.jaxrs.client.JaxRsClientFactory;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
+import java.util.Optional;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.equalTo;
@@ -31,6 +33,7 @@ public class SingleInstanceClusterControllerClientFactoryTest {
private static final HostName HOST_NAME_2 = new HostName("host2");
private static final HostName HOST_NAME_3 = new HostName("host3");
+ OrchestratorContext context = mock(OrchestratorContext.class);
private final ClusterControllerJaxRsApi mockApi = mock(ClusterControllerJaxRsApi.class);
private final JaxRsClientFactory jaxRsClientFactory = mock(JaxRsClientFactory.class);
private final ClusterControllerClientFactory clientFactory
@@ -64,8 +67,9 @@ public class SingleInstanceClusterControllerClientFactoryTest {
public void testCreateClientWithSingleClusterControllerInstance() throws Exception {
final List<HostName> clusterControllers = Arrays.asList(HOST_NAME_1);
+ when(context.getSuboperationTimeoutInSeconds()).thenReturn(Optional.of(1.0f));
clientFactory.createClient(clusterControllers, "clusterName")
- .setNodeState(0, ClusterControllerNodeState.MAINTENANCE);
+ .setNodeState(context, 0, ClusterControllerNodeState.MAINTENANCE);
verify(jaxRsClientFactory).createClient(
ClusterControllerJaxRsApi.class,
@@ -91,8 +95,9 @@ public class SingleInstanceClusterControllerClientFactoryTest {
public void testCreateClientWithThreeClusterControllerInstances() throws Exception {
final List<HostName> clusterControllers = Arrays.asList(HOST_NAME_1, HOST_NAME_2, HOST_NAME_3);
+ when(context.getSuboperationTimeoutInSeconds()).thenReturn(Optional.of(1.0f));
clientFactory.createClient(clusterControllers, "clusterName")
- .setNodeState(0, ClusterControllerNodeState.MAINTENANCE);
+ .setNodeState(context, 0, ClusterControllerNodeState.MAINTENANCE);
verify(jaxRsClientFactory).createClient(
eq(ClusterControllerJaxRsApi.class),
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java
index 220371c4a17..329c9576f2c 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/policy/HostedVespaPolicyTest.java
@@ -5,6 +5,7 @@ package com.yahoo.vespa.orchestrator.policy;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.applicationmodel.HostName;
import com.yahoo.vespa.orchestrator.OrchestrationException;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerClient;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerClientFactory;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerNodeState;
@@ -70,7 +71,8 @@ public class HostedVespaPolicyTest {
InOrder order = inOrder(applicationApi, clusterPolicy, storageNode1, storageNode3);
- policy.grantSuspensionRequest(applicationApi);
+ OrchestratorContext context = mock(OrchestratorContext.class);
+ policy.grantSuspensionRequest(context, applicationApi);
order.verify(applicationApi).getClusters();
order.verify(clusterPolicy).verifyGroupGoingDownIsFine(clusterApi1);
@@ -78,8 +80,8 @@ public class HostedVespaPolicyTest {
order.verify(clusterPolicy).verifyGroupGoingDownIsFine(clusterApi3);
order.verify(applicationApi).getUpStorageNodesInGroupInClusterOrder();
- order.verify(storageNode1).setNodeState(ClusterControllerNodeState.MAINTENANCE);
- order.verify(storageNode3).setNodeState(ClusterControllerNodeState.MAINTENANCE);
+ order.verify(storageNode1).setNodeState(context, ClusterControllerNodeState.MAINTENANCE);
+ order.verify(storageNode3).setNodeState(context, ClusterControllerNodeState.MAINTENANCE);
order.verify(applicationApi).getNodesInGroupWithStatus(HostStatus.NO_REMARKS);
order.verify(applicationApi).setHostState(hostName1, HostStatus.ALLOWED_TO_BE_DOWN);
@@ -120,7 +122,8 @@ public class HostedVespaPolicyTest {
InOrder order = inOrder(applicationApi, clusterPolicy, storageNode1, storageNode3);
- policy.acquirePermissionToRemove(applicationApi);
+ OrchestratorContext context = mock(OrchestratorContext.class);
+ policy.acquirePermissionToRemove(context, applicationApi);
order.verify(applicationApi).getClusters();
order.verify(clusterPolicy).verifyGroupGoingDownPermanentlyIsFine(clusterApi1);
@@ -128,8 +131,8 @@ public class HostedVespaPolicyTest {
order.verify(clusterPolicy).verifyGroupGoingDownPermanentlyIsFine(clusterApi3);
order.verify(applicationApi).getStorageNodesInGroupInClusterOrder();
- order.verify(storageNode1).setNodeState(ClusterControllerNodeState.DOWN);
- order.verify(storageNode3).setNodeState(ClusterControllerNodeState.DOWN);
+ order.verify(storageNode1).setNodeState(context, ClusterControllerNodeState.DOWN);
+ order.verify(storageNode3).setNodeState(context, ClusterControllerNodeState.DOWN);
order.verify(applicationApi).getNodesInGroupWithStatus(HostStatus.NO_REMARKS);
order.verify(applicationApi).setHostState(hostName1, HostStatus.ALLOWED_TO_BE_DOWN);
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostResourceTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostResourceTest.java
index 2c7db25ae30..49f1a33febb 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostResourceTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostResourceTest.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.orchestrator.resources;
+import com.yahoo.jdisc.Timer;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
import com.yahoo.vespa.applicationmodel.ApplicationInstanceId;
import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
@@ -16,6 +17,7 @@ import com.yahoo.vespa.orchestrator.Host;
import com.yahoo.vespa.orchestrator.InstanceLookupService;
import com.yahoo.vespa.orchestrator.OrchestrationException;
import com.yahoo.vespa.orchestrator.Orchestrator;
+import com.yahoo.vespa.orchestrator.OrchestratorContext;
import com.yahoo.vespa.orchestrator.OrchestratorImpl;
import com.yahoo.vespa.orchestrator.controller.ClusterControllerClientFactoryMock;
import com.yahoo.vespa.orchestrator.model.ApplicationApi;
@@ -59,7 +61,7 @@ import static org.mockito.Mockito.when;
* @author hakonhall
*/
public class HostResourceTest {
-
+ private static final Timer timer = mock(Timer.class);
private static final int SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS = 0;
private static final TenantId TENANT_ID = new TenantId("tenantId");
private static final ApplicationInstanceId APPLICATION_INSTANCE_ID = new ApplicationInstanceId("applicationId");
@@ -110,28 +112,20 @@ public class HostResourceTest {
private static class AlwaysAllowPolicy implements Policy {
@Override
- public void grantSuspensionRequest(
- ApplicationInstance applicationInstance,
- HostName hostName,
- MutableStatusRegistry hostStatusService) {
-
- }
-
- @Override
- public void grantSuspensionRequest(ApplicationApi applicationApi) {
+ public void grantSuspensionRequest(OrchestratorContext context, ApplicationApi applicationApi) {
}
@Override
- public void releaseSuspensionGrant(ApplicationApi application) {
+ public void releaseSuspensionGrant(OrchestratorContext context, ApplicationApi application) {
}
@Override
- public void acquirePermissionToRemove(ApplicationApi applicationApi) {
+ public void acquirePermissionToRemove(OrchestratorContext context, ApplicationApi applicationApi) {
}
@Override
public void releaseSuspensionGrant(
- ApplicationInstance applicationInstance,
+ OrchestratorContext context, ApplicationInstance applicationInstance,
HostName hostName,
MutableStatusRegistry hostStatusRegistry) {
}
@@ -141,14 +135,16 @@ public class HostResourceTest {
new AlwaysAllowPolicy(),
new ClusterControllerClientFactoryMock(),
EVERY_HOST_IS_UP_HOST_STATUS_SERVICE, mockInstanceLookupService,
- SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS
+ SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS,
+ timer
);
private static final OrchestratorImpl hostNotFoundOrchestrator = new OrchestratorImpl(
new AlwaysAllowPolicy(),
new ClusterControllerClientFactoryMock(),
EVERY_HOST_IS_UP_HOST_STATUS_SERVICE, alwaysEmptyInstanceLookUpService,
- SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS
+ SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS,
+ timer
);
private final UriInfo uriInfo = mock(UriInfo.class);
@@ -209,31 +205,23 @@ public class HostResourceTest {
private static class AlwaysFailPolicy implements Policy {
@Override
- public void grantSuspensionRequest(
- ApplicationInstance applicationInstance,
- HostName hostName,
- MutableStatusRegistry hostStatusRegistry) throws HostStateChangeDeniedException {
- doThrow();
- }
-
- @Override
- public void grantSuspensionRequest(ApplicationApi applicationApi) throws HostStateChangeDeniedException {
+ public void grantSuspensionRequest(OrchestratorContext context, ApplicationApi applicationApi) throws HostStateChangeDeniedException {
doThrow();
}
@Override
- public void releaseSuspensionGrant(ApplicationApi application) throws HostStateChangeDeniedException {
+ public void releaseSuspensionGrant(OrchestratorContext context, ApplicationApi application) throws HostStateChangeDeniedException {
doThrow();
}
@Override
- public void acquirePermissionToRemove(ApplicationApi applicationApi) throws HostStateChangeDeniedException {
+ public void acquirePermissionToRemove(OrchestratorContext context, ApplicationApi applicationApi) throws HostStateChangeDeniedException {
doThrow();
}
@Override
public void releaseSuspensionGrant(
- ApplicationInstance applicationInstance,
+ OrchestratorContext context, ApplicationInstance applicationInstance,
HostName hostName,
MutableStatusRegistry hostStatusRegistry) throws HostStateChangeDeniedException {
doThrow();
@@ -253,7 +241,8 @@ public class HostResourceTest {
new AlwaysFailPolicy(),
new ClusterControllerClientFactoryMock(),
EVERY_HOST_IS_UP_HOST_STATUS_SERVICE,mockInstanceLookupService,
- SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS);
+ SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS,
+ timer);
try {
HostResource hostResource = new HostResource(alwaysRejectResolver, uriInfo);
@@ -271,7 +260,8 @@ public class HostResourceTest {
new ClusterControllerClientFactoryMock(),
EVERY_HOST_IS_UP_HOST_STATUS_SERVICE,
mockInstanceLookupService,
- SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS);
+ SERVICE_MONITOR_CONVERGENCE_LATENCY_SECONDS,
+ timer);
try {
HostSuspensionResource hostSuspensionResource = new HostSuspensionResource(alwaysRejectResolver);