summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java7
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java26
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java10
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java26
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/CloudWatch.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultMetrics.java (renamed from config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultPublicMetrics.java)11
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultPublicConsumer.java29
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricSet.java14
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricsConsumer.java38
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricsConsumer.java32
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/Metrics.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/PredefinedMetricSets.java12
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/xml/MetricsBuilder.java8
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/CloudWatchValidator.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java7
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java118
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java26
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java14
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java86
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/NodeResourcesTuning.java50
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ThreadPoolExecutorComponent.java70
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/BundleInstantiationSpecificationBuilder.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java40
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java13
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java80
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java3
-rw-r--r--config-model/src/main/resources/schema/containercluster.rnc19
-rw-r--r--config-model/src/main/resources/schema/federation.rnc2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsConsumersTest.java17
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java6
-rwxr-xr-xconfig-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java16
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java37
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/SearchBuilderTest.java57
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java28
-rw-r--r--config-model/src/test/schema-test-files/services.xml20
37 files changed, 539 insertions, 400 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
index fc799449379..22bdf31350a 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
@@ -37,6 +37,7 @@ public class TestProperties implements ModelContext.Properties {
private boolean useDedicatedNodeForLogserver = false;
private boolean useContentNodeBtreeDb = false;
private boolean useThreePhaseUpdates = false;
+ private boolean useDirectStorageApiRpc = false;
private double defaultTermwiseLimit = 1.0;
private double threadPoolSizeFactor = 0.0;
private double queueSizeFactor = 0.0;
@@ -73,6 +74,7 @@ public class TestProperties implements ModelContext.Properties {
}
@Override public boolean useContentNodeBtreeDb() { return useContentNodeBtreeDb; }
@Override public boolean useThreePhaseUpdates() { return useThreePhaseUpdates; }
+ @Override public boolean useDirectStorageApiRpc() { return useDirectStorageApiRpc; }
@Override public Optional<AthenzDomain> athenzDomain() { return Optional.ofNullable(athenzDomain); }
@Override public Optional<ApplicationRoles> applicationRoles() { return Optional.ofNullable(applicationRoles); }
@Override public String responseSequencerType() { return responseSequencerType; }
@@ -113,6 +115,11 @@ public class TestProperties implements ModelContext.Properties {
return this;
}
+ public TestProperties setUseDirectStorageApiRpc(boolean useDirectStorageApiRpc) {
+ this.useDirectStorageApiRpc = useDirectStorageApiRpc;
+ return this;
+ }
+
public TestProperties setThreadPoolSizeFactor(double threadPoolSizeFactor) {
this.threadPoolSizeFactor = threadPoolSizeFactor;
return this;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
index 1b5be1c2f97..3f432620b90 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java
@@ -31,7 +31,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
-import static com.yahoo.vespa.model.admin.monitoring.MetricSet.emptyMetricSet;
+import static com.yahoo.vespa.model.admin.monitoring.MetricSet.empty;
/**
* This is the admin pseudo-plugin of the Vespa model, responsible for
@@ -49,7 +49,7 @@ public class Admin extends AbstractConfigProducer implements Serializable {
private final Metrics metrics;
private MetricsProxyContainerCluster metricsProxyCluster;
- private MetricSet additionalDefaultMetrics = emptyMetricSet();
+ private MetricSet additionalDefaultMetrics = empty();
private final List<Slobrok> slobroks = new ArrayList<>();
private Configserver defaultConfigserver;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java
index 3f9edae10c0..2c039118cb9 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/ConsumersConfigGenerator.java
@@ -12,8 +12,6 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-import static com.yahoo.vespa.model.admin.monitoring.VespaMetricsConsumer.VESPA_CONSUMER_ID;
-
/**
* Helper class to generate config for metrics consumers.
*
@@ -22,14 +20,16 @@ import static com.yahoo.vespa.model.admin.monitoring.VespaMetricsConsumer.VESPA_
class ConsumersConfigGenerator {
/**
- * @param userConsumers The consumers set up by the user in services.xml
- * @return A list of consumer builders (a mapping from consumer to its metrics)
+ * @param userConsumers the consumers set up by the user in services.xml
+ * @return a list of consumer builders (a mapping from consumer to its metrics)
*/
static List<Consumer.Builder> generateConsumers(MetricsConsumer defaultConsumer,
Map<String, MetricsConsumer> userConsumers) {
- // Normally, the user given consumers should not contain VESPA_CONSUMER_ID, but it's allowed for some internally used applications.
+ // Normally, the user given consumers should not contain VESPA_CONSUMER_ID,
+ // but it's allowed for some internally used applications.
var allConsumers = new LinkedHashMap<>(userConsumers);
- allConsumers.put(VESPA_CONSUMER_ID, combineConsumers(defaultConsumer, allConsumers.get(VESPA_CONSUMER_ID)));
+ allConsumers.put(MetricsConsumer.vespa.id(),
+ combineConsumers(defaultConsumer, allConsumers.get(MetricsConsumer.vespa.id())));
return allConsumers.values().stream()
.map(ConsumersConfigGenerator::toConsumerBuilder)
@@ -45,18 +45,18 @@ class ConsumersConfigGenerator {
*/
private static MetricsConsumer combineConsumers(MetricsConsumer original, MetricsConsumer overriding) {
if (overriding == null) return original;
- return addMetrics(original, overriding.getMetrics());
+ return addMetrics(original, overriding.metrics());
}
static MetricsConsumer addMetrics(MetricsConsumer original, Map<String, Metric> metrics) {
if (metrics == null) return original;
- Map<String, Metric> combinedMetrics = new LinkedHashMap<>(original.getMetrics());
+ Map<String, Metric> combinedMetrics = new LinkedHashMap<>(original.metrics());
metrics.forEach((name, newMetric) ->
- combinedMetrics.put(name, combineMetrics(original.getMetrics().get(name), newMetric)));
+ combinedMetrics.put(name, combineMetrics(original.metrics().get(name), newMetric)));
- return new MetricsConsumer(original.getId(),
- new MetricSet(original.getMetricSet().getId(), combinedMetrics.values()));
+ return new MetricsConsumer(original.id(),
+ new MetricSet(original.metricSet().getId(), combinedMetrics.values()));
}
private static Metric combineMetrics(Metric original, Metric newMetric) {
@@ -64,8 +64,8 @@ class ConsumersConfigGenerator {
}
static Consumer.Builder toConsumerBuilder(MetricsConsumer consumer) {
- Consumer.Builder builder = new Consumer.Builder().name(consumer.getId());
- consumer.getMetrics().values().forEach(metric -> builder.metric(toConsumerMetricBuilder(metric)));
+ Consumer.Builder builder = new Consumer.Builder().name(consumer.id());
+ consumer.metrics().values().forEach(metric -> builder.metric(toConsumerMetricBuilder(metric)));
return builder;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java
index b5936887b50..fbf6dcfd5eb 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerCluster.java
@@ -56,9 +56,7 @@ import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyContainerClus
import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyContainerCluster.AppDimensionNames.LEGACY_APPLICATION;
import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyContainerCluster.AppDimensionNames.SYSTEM;
import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyContainerCluster.AppDimensionNames.TENANT;
-import static com.yahoo.vespa.model.admin.monitoring.DefaultPublicConsumer.getDefaultPublicConsumer;
-import static com.yahoo.vespa.model.admin.monitoring.MetricSet.emptyMetricSet;
-import static com.yahoo.vespa.model.admin.monitoring.VespaMetricsConsumer.getVespaMetricsConsumer;
+import static com.yahoo.vespa.model.admin.monitoring.MetricSet.empty;
/**
* Container cluster for metrics proxy containers.
@@ -161,10 +159,10 @@ public class MetricsProxyContainerCluster extends ContainerCluster<MetricsProxyC
@Override
public void getConfig(ConsumersConfig.Builder builder) {
- var amendedVespaConsumer = addMetrics(getVespaMetricsConsumer(), getAdditionalDefaultMetrics().getMetrics());
+ var amendedVespaConsumer = addMetrics(MetricsConsumer.vespa, getAdditionalDefaultMetrics().getMetrics());
builder.consumer.addAll(generateConsumers(amendedVespaConsumer, getUserMetricsConsumers()));
- builder.consumer.add(toConsumerBuilder(getDefaultPublicConsumer()));
+ builder.consumer.add(toConsumerBuilder(MetricsConsumer.defaultConsumer));
}
@Override
@@ -210,7 +208,7 @@ public class MetricsProxyContainerCluster extends ContainerCluster<MetricsProxyC
private MetricSet getAdditionalDefaultMetrics() {
return getAdmin()
.map(Admin::getAdditionalDefaultMetrics)
- .orElse(emptyMetricSet());
+ .orElse(empty());
}
// Returns the metrics consumers from services.xml
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java
new file mode 100644
index 00000000000..f6f51ed91fb
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/AutoscalingMetrics.java
@@ -0,0 +1,26 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.admin.monitoring;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Metrics used for autoscaling
+ *
+ * @author bratseth
+ */
+public class AutoscalingMetrics {
+
+ public static final MetricSet autoscalingMetricSet = create();
+
+ private static MetricSet create() {
+ return new MetricSet("autoscaling",
+ metrics("cpu.util", "mem_total.util", "disk.util"));
+ }
+
+ private static Set<Metric> metrics(String ... names) {
+ return Arrays.stream(names).map(Metric::new).collect(Collectors.toSet());
+ }
+
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/CloudWatch.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/CloudWatch.java
index 5351c3fb3a7..66a278b3fb6 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/CloudWatch.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/CloudWatch.java
@@ -8,6 +8,7 @@ import java.util.Optional;
* @author gjoranv
*/
public class CloudWatch {
+
private final String region;
private final String namespace;
private final MetricsConsumer consumer;
@@ -23,7 +24,7 @@ public class CloudWatch {
public String region() { return region; }
public String namespace() { return namespace; }
- public String consumer() { return consumer.getId(); }
+ public String consumer() { return consumer.id(); }
public Optional<HostedAuth> hostedAuth() {return Optional.ofNullable(hostedAuth); }
public Optional<SharedCredentials> sharedCredentials() {return Optional.ofNullable(sharedCredentials); }
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultPublicMetrics.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultMetrics.java
index c80cebe3d5b..adc0d0b1db8 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultPublicMetrics.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultMetrics.java
@@ -9,7 +9,6 @@ import java.util.LinkedHashSet;
import java.util.Set;
import static com.yahoo.vespa.model.admin.monitoring.DefaultVespaMetrics.defaultVespaMetricSet;
-import static java.util.Collections.emptyList;
import static java.util.Collections.singleton;
/**
@@ -18,14 +17,14 @@ import static java.util.Collections.singleton;
*
* @author gjoranv
*/
-public class DefaultPublicMetrics {
+public class DefaultMetrics {
- public static final String DEFAULT_METRIC_SET_ID = "default";
+ public static final String defaultMetricSetId = "default";
- public static MetricSet defaultPublicMetricSet = createMetricSet();
+ public static MetricSet defaultMetricSet = createMetricSet();
private static MetricSet createMetricSet() {
- return new MetricSet(DEFAULT_METRIC_SET_ID,
+ return new MetricSet(defaultMetricSetId,
getAllMetrics(),
singleton(defaultVespaMetricSet));
}
@@ -95,6 +94,6 @@ public class DefaultPublicMetrics {
return metrics;
}
- private DefaultPublicMetrics() { }
+ private DefaultMetrics() { }
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultPublicConsumer.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultPublicConsumer.java
deleted file mode 100644
index 68b1fc3c983..00000000000
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/DefaultPublicConsumer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-package com.yahoo.vespa.model.admin.monitoring;
-
-import ai.vespa.metricsproxy.http.ValuesFetcher;
-import com.google.common.collect.ImmutableList;
-
-import static com.yahoo.vespa.model.admin.monitoring.DefaultPublicMetrics.defaultPublicMetricSet;
-import static com.yahoo.vespa.model.admin.monitoring.DefaultVespaMetrics.defaultVespaMetricSet;
-import static com.yahoo.vespa.model.admin.monitoring.SystemMetrics.systemMetricSet;
-import static java.util.Collections.emptyList;
-
-/**
- * @author gjoranv
- */
-public class DefaultPublicConsumer {
-
- public static final String DEFAULT_PUBLIC_CONSUMER_ID = ValuesFetcher.DEFAULT_PUBLIC_CONSUMER_ID.id;
-
- private static final MetricSet publicConsumerMetrics = new MetricSet("public-consumer-metrics",
- emptyList(),
- ImmutableList.of(defaultPublicMetricSet,
- systemMetricSet));
-
- public static MetricsConsumer getDefaultPublicConsumer() {
- return new MetricsConsumer(DEFAULT_PUBLIC_CONSUMER_ID, publicConsumerMetrics);
- }
-
-}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricSet.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricSet.java
index d879a6f445d..30797f27789 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricSet.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricSet.java
@@ -24,21 +24,19 @@ public class MetricSet {
private final Map<String, Metric> metrics;
private final Set<MetricSet> children;
+ public MetricSet(String id, Collection<Metric> metrics) {
+ this(id, metrics, Collections.emptySet());
+ }
public MetricSet(String id, Collection<Metric> metrics, Collection<MetricSet> children) {
- Objects.requireNonNull(id, "Id cannot be null or empty.");
+ this.id = Objects.requireNonNull(id, "Id cannot be null or empty.");
- this.id = id;
this.metrics = toMapByName(metrics);
this.children = new LinkedHashSet<>(children);
}
- public MetricSet(String id, Collection<Metric> metrics) {
- this(id, metrics, Collections.emptySet());
- }
-
- public static MetricSet emptyMetricSet() {
- return new MetricSet("empty", Collections.emptySet());
+ public static MetricSet empty() {
+ return new MetricSet("empty", Set.of());
}
public final String getId() { return id; }
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricsConsumer.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricsConsumer.java
index a8fbcf50b02..698b01c306a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricsConsumer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/MetricsConsumer.java
@@ -1,26 +1,44 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.admin.monitoring;
-import javax.annotation.concurrent.Immutable;
+import ai.vespa.metricsproxy.core.VespaMetrics;
+import ai.vespa.metricsproxy.http.ValuesFetcher;
+
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import static com.yahoo.vespa.model.admin.monitoring.AutoscalingMetrics.autoscalingMetricSet;
+import static com.yahoo.vespa.model.admin.monitoring.DefaultMetrics.defaultMetricSet;
+import static com.yahoo.vespa.model.admin.monitoring.NetworkMetrics.networkMetricSet;
+import static com.yahoo.vespa.model.admin.monitoring.SystemMetrics.systemMetricSet;
+import static com.yahoo.vespa.model.admin.monitoring.VespaMetricSet.vespaMetricSet;
import static java.util.Collections.unmodifiableList;
/**
- * Represents an arbitrary metric consumer
+ * A metric consumer is a set of metrics given an id that can be requested at runtime.
*
- * @author trygve
+ * @author Trygve Berdal
* @author gjoranv
*/
-@Immutable
+// TODO: This construct seems redundant when we have metrics sets
public class MetricsConsumer {
+ // Pre-defined consumers
+ public static final MetricsConsumer vespa =
+ consumer(VespaMetrics.vespaMetricsConsumerId.id, vespaMetricSet, systemMetricSet, networkMetricSet);
+ public static final MetricsConsumer defaultConsumer =
+ consumer(ValuesFetcher.defaultMetricsConsumerId.id, defaultMetricSet, systemMetricSet);
+ // Referenced from com.yahoo.vespa.hosted.provision.autoscale.NodeMetricsFetcher
+ public static final MetricsConsumer autoscaling =
+ consumer("autoscaling", autoscalingMetricSet);
+
private final String id;
private final MetricSet metricSet;
+ // TODO: This shouldn't be here
private final List<CloudWatch> cloudWatches = new ArrayList<>();
/**
@@ -32,16 +50,16 @@ public class MetricsConsumer {
this.metricSet = Objects.requireNonNull(metricSet, "A consumer must have a non-null metric set.");
}
- public String getId() {
+ public String id() {
return id;
}
- public MetricSet getMetricSet() { return metricSet; }
+ public MetricSet metricSet() { return metricSet; }
/**
- * @return Map of metric with metric name as key
+ * @return map of metric with metric name as key
*/
- public Map<String, Metric> getMetrics() {
+ public Map<String, Metric> metrics() {
return metricSet.getMetrics();
}
@@ -53,4 +71,8 @@ public class MetricsConsumer {
return unmodifiableList(cloudWatches);
}
+ private static MetricsConsumer consumer(String id, MetricSet ... metricSets) {
+ return new MetricsConsumer(id, new MetricSet(id + "-consumer-metrics", List.of(), Arrays.asList(metricSets)));
+ }
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricsConsumer.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricsConsumer.java
deleted file mode 100644
index 9f3bfdc8ae8..00000000000
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricsConsumer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.model.admin.monitoring;
-
-import ai.vespa.metricsproxy.core.VespaMetrics;
-import com.google.common.collect.ImmutableList;
-
-import static com.yahoo.vespa.model.admin.monitoring.NetworkMetrics.networkMetricSet;
-import static com.yahoo.vespa.model.admin.monitoring.SystemMetrics.systemMetricSet;
-import static com.yahoo.vespa.model.admin.monitoring.VespaMetricSet.vespaMetricSet;
-import static java.util.Collections.emptyList;
-
-/**
- * This class sets up the 'Vespa' metrics consumer, which is mainly used for Yamas in hosted Vespa.
- *
- * @author trygve
- * @author gjoranv
- */
-public class VespaMetricsConsumer {
-
- public static final String VESPA_CONSUMER_ID = VespaMetrics.VESPA_CONSUMER_ID.id;
-
- private static final MetricSet vespaConsumerMetrics = new MetricSet("vespa-consumer-metrics",
- emptyList(),
- ImmutableList.of(vespaMetricSet,
- systemMetricSet,
- networkMetricSet));
-
- public static MetricsConsumer getVespaMetricsConsumer() {
- return new MetricsConsumer(VESPA_CONSUMER_ID, vespaConsumerMetrics);
- }
-
-}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/Metrics.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/Metrics.java
index 1f81f16a80b..6f9e9a08aa6 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/Metrics.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/Metrics.java
@@ -17,7 +17,7 @@ public class Metrics {
private final Map<String, MetricsConsumer> consumers = new LinkedHashMap<>();
public void addConsumer(MetricsConsumer consumer) {
- consumers.put(consumer.getId(), consumer);
+ consumers.put(consumer.id(), consumer);
}
public Map<String, MetricsConsumer> getConsumers() {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/PredefinedMetricSets.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/PredefinedMetricSets.java
index 694108d4bb1..dd514f1e245 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/PredefinedMetricSets.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/PredefinedMetricSets.java
@@ -7,7 +7,8 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
-import static com.yahoo.vespa.model.admin.monitoring.DefaultPublicMetrics.defaultPublicMetricSet;
+import static com.yahoo.vespa.model.admin.monitoring.AutoscalingMetrics.autoscalingMetricSet;
+import static com.yahoo.vespa.model.admin.monitoring.DefaultMetrics.defaultMetricSet;
import static com.yahoo.vespa.model.admin.monitoring.NetworkMetrics.networkMetricSet;
import static com.yahoo.vespa.model.admin.monitoring.SystemMetrics.systemMetricSet;
import static com.yahoo.vespa.model.admin.monitoring.DefaultVespaMetrics.defaultVespaMetricSet;
@@ -20,14 +21,17 @@ import static com.yahoo.vespa.model.admin.monitoring.VespaMetricSet.vespaMetricS
*/
public class PredefinedMetricSets {
- public static final Map<String, MetricSet> predefinedMetricSets = toMapById(
- defaultPublicMetricSet,
+ private static final Map<String, MetricSet> sets = toMapById(
+ defaultMetricSet,
defaultVespaMetricSet,
vespaMetricSet,
systemMetricSet,
- networkMetricSet
+ networkMetricSet,
+ autoscalingMetricSet
);
+ public static Map<String, MetricSet> get() { return sets; }
+
private static Map<String, MetricSet> toMapById(MetricSet... metricSets) {
Map<String, MetricSet> availableMetricSets = new LinkedHashMap<>();
for (MetricSet metricSet : metricSets) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/xml/MetricsBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/xml/MetricsBuilder.java
index b686288868f..919830d912f 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/xml/MetricsBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/builder/xml/MetricsBuilder.java
@@ -14,8 +14,6 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-import static com.yahoo.vespa.model.admin.monitoring.DefaultPublicConsumer.DEFAULT_PUBLIC_CONSUMER_ID;
-import static com.yahoo.vespa.model.admin.monitoring.VespaMetricsConsumer.VESPA_CONSUMER_ID;
import static com.yahoo.vespa.model.admin.monitoring.DefaultVespaMetrics.defaultVespaMetricSet;
import static com.yahoo.vespa.model.admin.monitoring.SystemMetrics.systemMetricSet;
@@ -85,11 +83,11 @@ public class MetricsBuilder {
}
private void throwIfIllegalConsumerId(Metrics metrics, String consumerId) {
- if (consumerId.equalsIgnoreCase(VESPA_CONSUMER_ID) && applicationType != ApplicationType.HOSTED_INFRASTRUCTURE)
+ if (consumerId.equalsIgnoreCase(MetricsConsumer.vespa.id()) && applicationType != ApplicationType.HOSTED_INFRASTRUCTURE)
throw new IllegalArgumentException("'Vespa' is not allowed as metrics consumer id (case is ignored.)");
- if (consumerId.equalsIgnoreCase(DEFAULT_PUBLIC_CONSUMER_ID))
- throw new IllegalArgumentException("'" + DEFAULT_PUBLIC_CONSUMER_ID + "' is not allowed as metrics consumer id (case is ignored.)");
+ if (consumerId.equalsIgnoreCase(MetricsConsumer.defaultConsumer.id()))
+ throw new IllegalArgumentException("'" + MetricsConsumer.defaultConsumer.id() + "' is not allowed as metrics consumer id (case is ignored.)");
if (metrics.hasConsumerIgnoreCase(consumerId))
throw new IllegalArgumentException("'" + consumerId + "' is used as id for two metrics consumers (case is ignored.)");
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/CloudWatchValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/CloudWatchValidator.java
index 462ac39fa84..025b7875677 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/CloudWatchValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/CloudWatchValidator.java
@@ -31,7 +31,7 @@ public class CloudWatchValidator extends Validator {
}
private List<String> consumerIds(List<MetricsConsumer> offendingConsumers) {
- return offendingConsumers.stream().map(MetricsConsumer::getId).collect(toList());
+ return offendingConsumers.stream().map(MetricsConsumer::id).collect(toList());
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java
index d2f06da992c..b643f771d73 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java
@@ -18,6 +18,7 @@ import com.yahoo.vespa.model.admin.ModelConfigProvider;
import com.yahoo.vespa.model.admin.monitoring.DefaultMonitoring;
import com.yahoo.vespa.model.admin.monitoring.Monitoring;
import com.yahoo.vespa.model.admin.monitoring.builder.Metrics;
+import com.yahoo.vespa.model.admin.monitoring.builder.PredefinedMetricSets;
import com.yahoo.vespa.model.admin.monitoring.builder.xml.MetricsBuilder;
import com.yahoo.vespa.model.filedistribution.FileDistributionConfigProducer;
import org.w3c.dom.Element;
@@ -25,8 +26,6 @@ import org.w3c.dom.Element;
import java.util.ArrayList;
import java.util.List;
-import static com.yahoo.vespa.model.admin.monitoring.builder.PredefinedMetricSets.predefinedMetricSets;
-
/**
* A base class for admin model builders, to support common functionality across versions.
*
@@ -69,8 +68,8 @@ public abstract class DomAdminBuilderBase extends VespaDomBuilder.DomConfigProdu
@Override
protected Admin doBuild(DeployState deployState, AbstractConfigProducer parent, Element adminElement) {
Monitoring monitoring = getMonitoring(XML.getChild(adminElement,"monitoring"), deployState.isHosted());
- Metrics metrics = new MetricsBuilder(applicationType, predefinedMetricSets)
- .buildMetrics(XML.getChild(adminElement, "metrics"));
+ Metrics metrics = new MetricsBuilder(applicationType, PredefinedMetricSets.get())
+ .buildMetrics(XML.getChild(adminElement, "metrics"));
FileDistributionConfigProducer fileDistributionConfigProducer = getFileDistributionConfigProducer(parent, deployState.isHosted());
Admin admin = new Admin(parent, monitoring, metrics, multitenant, fileDistributionConfigProducer, deployState.isHosted());
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java b/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
index 9012cc2aba0..feaa6eb5940 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/clients/ContainerDocumentApi.java
@@ -3,17 +3,16 @@ package com.yahoo.vespa.model.clients;
import com.yahoo.config.model.producer.AbstractConfigProducer;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
+import com.yahoo.container.handler.threadpool.ContainerThreadpoolConfig;
import com.yahoo.osgi.provider.model.ComponentModel;
import com.yahoo.vespa.model.container.ContainerCluster;
-import com.yahoo.vespa.model.container.ThreadPoolExecutorComponent;
+import com.yahoo.vespa.model.container.ContainerThreadpool;
import com.yahoo.vespa.model.container.component.Handler;
import com.yahoo.vespa.model.container.component.SystemBindingPattern;
import com.yahoo.vespa.model.container.component.UserBindingPattern;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
/**
* @author Einar M R Rosenvinge
@@ -24,51 +23,31 @@ public class ContainerDocumentApi {
private static final int FALLBACK_MAX_POOL_SIZE = 0; // Use fallback based on actual logical core count on host
private static final int FALLBACK_CORE_POOL_SIZE = 0; // Use fallback based on actual logical core count on host
- private final ContainerCluster<?> cluster;
- private final Options options;
- private final Handler<AbstractConfigProducer<?>> feedHandler;
- private final Handler<AbstractConfigProducer<?>> restApiHandler;
-
public ContainerDocumentApi(ContainerCluster<?> cluster, Options options) {
- this.cluster = cluster;
- this.options = options;
- this.restApiHandler = addRestApiHandler(cluster, options);
- this.feedHandler = addFeedHandler(cluster, options);
- }
-
-
- public void addNodesDependentThreadpoolConfiguration() {
- if (cluster.getContainers().isEmpty()) throw new IllegalStateException("Cluster is empty");
- ThreadPoolExecutorComponent feedHandlerExecutor = newExecutorComponent("feedapi-handler", cluster, options);
- feedHandler.inject(feedHandlerExecutor);
- feedHandler.addComponent(feedHandlerExecutor);
- ThreadPoolExecutorComponent restApiHandlerExecutor = newExecutorComponent("restapi-handler", cluster, options);
- restApiHandler.inject(restApiHandlerExecutor);
- restApiHandler.addComponent(restApiHandlerExecutor);
+ addRestApiHandler(cluster, options);
+ addFeedHandler(cluster, options);
}
- private static Handler<AbstractConfigProducer<?>> addFeedHandler(ContainerCluster<?> cluster, Options options) {
+ private static void addFeedHandler(ContainerCluster<?> cluster, Options options) {
String bindingSuffix = ContainerCluster.RESERVED_URI_PREFIX + "/feedapi";
var handler = newVespaClientHandler(
"com.yahoo.vespa.http.server.FeedHandler", bindingSuffix, options);
cluster.addComponent(handler);
- return handler;
+ var executor = new Threadpool(
+ "feedapi-handler", cluster, options.feedApiThreadpoolOptions, options.feedThreadPoolSizeFactor);
+ handler.inject(executor);
+ handler.addComponent(executor);
}
- private static Handler<AbstractConfigProducer<?>> addRestApiHandler(ContainerCluster<?> cluster, Options options) {
+ private static void addRestApiHandler(ContainerCluster<?> cluster, Options options) {
var handler = newVespaClientHandler(
"com.yahoo.document.restapi.resource.RestApi", "/document/v1/*", options);
cluster.addComponent(handler);
- return handler;
- }
-
- private static ThreadPoolExecutorComponent newExecutorComponent(String name, ContainerCluster<?> cluster, Options options) {
- return new ThreadPoolExecutorComponent.Builder(name)
- .maxPoolSize(maxPoolSize(cluster, options))
- .corePoolSize(corePoolSize(cluster, options))
- .queueSize(500)
- .build();
+ var executor = new Threadpool(
+ "restapi-handler", cluster, options.restApiThreadpoolOptions, options.feedThreadPoolSizeFactor);
+ handler.inject(executor);
+ handler.addComponent(executor);
}
private static Handler<AbstractConfigProducer<?>> newVespaClientHandler(
@@ -92,37 +71,60 @@ public class ContainerDocumentApi {
return handler;
}
- private static int maxPoolSize(ContainerCluster<?> cluster, Options options) {
- double vcpu = vcpu(cluster);
- if (vcpu == 0) return FALLBACK_MAX_POOL_SIZE;
- return Math.max(2, (int)Math.ceil(vcpu * options.feedThreadPoolSizeFactor));
- }
+ public static final class Options {
+ private final Collection<String> bindings;
+ private final ContainerThreadpool.UserOptions restApiThreadpoolOptions;
+ private final ContainerThreadpool.UserOptions feedApiThreadpoolOptions;
+ private final double feedThreadPoolSizeFactor;
- private static int corePoolSize(ContainerCluster<?> cluster, Options options) {
- double vcpu = vcpu(cluster);
- if (vcpu == 0) return FALLBACK_CORE_POOL_SIZE;
- return Math.max(1, (int)Math.ceil(vcpu * options.feedThreadPoolSizeFactor * 0.5));
+ public Options(Collection<String> bindings,
+ ContainerThreadpool.UserOptions restApiThreadpoolOptions,
+ ContainerThreadpool.UserOptions feedApiThreadpoolOptions,
+ double feedThreadPoolSizeFactor) {
+ this.bindings = Collections.unmodifiableCollection(bindings);
+ this.restApiThreadpoolOptions = restApiThreadpoolOptions;
+ this.feedApiThreadpoolOptions = feedApiThreadpoolOptions;
+ this.feedThreadPoolSizeFactor = feedThreadPoolSizeFactor;
+ }
}
- private static double vcpu(ContainerCluster<?> cluster) {
- List<Double> vcpus = cluster.getContainers().stream()
- .filter(c -> c.getHostResource() != null && c.getHostResource().realResources() != null)
- .map(c -> c.getHostResource().realResources().vcpu())
- .distinct()
- .collect(Collectors.toList());
- // We can only use host resource for calculation if all container nodes in the cluster are homogeneous (in terms of vcpu)
- if (vcpus.size() != 1 || vcpus.get(0) == 0) return 0;
- return vcpus.get(0);
- }
+ private static class Threadpool extends ContainerThreadpool {
- public static final class Options {
- private final Collection<String> bindings;
+ private final ContainerCluster<?> cluster;
private final double feedThreadPoolSizeFactor;
- public Options(Collection<String> bindings, double feedThreadPoolSizeFactor) {
- this.bindings = Collections.unmodifiableCollection(bindings);
+ Threadpool(String name,
+ ContainerCluster<?> cluster,
+ ContainerThreadpool.UserOptions threadpoolOptions,
+ double feedThreadPoolSizeFactor ) {
+ super(name, threadpoolOptions);
+ this.cluster = cluster;
this.feedThreadPoolSizeFactor = feedThreadPoolSizeFactor;
}
+
+ @Override
+ public void getConfig(ContainerThreadpoolConfig.Builder builder) {
+ super.getConfig(builder);
+
+ // User options overrides below configuration
+ if (hasUserOptions()) return;
+
+ builder.maxThreads(maxPoolSize());
+ builder.minThreads(minPoolSize());
+ builder.queueSize(500);
+ }
+
+ private int maxPoolSize() {
+ double vcpu = vcpu(cluster);
+ if (vcpu == 0) return FALLBACK_MAX_POOL_SIZE;
+ return Math.max(2, (int)Math.ceil(vcpu * feedThreadPoolSizeFactor));
+ }
+
+ private int minPoolSize() {
+ double vcpu = vcpu(cluster);
+ if (vcpu == 0) return FALLBACK_CORE_POOL_SIZE;
+ return Math.max(1, (int)Math.ceil(vcpu * feedThreadPoolSizeFactor * 0.5));
+ }
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
index 5207a0163cb..232552ea4ce 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
@@ -3,8 +3,8 @@ package com.yahoo.vespa.model.container;
import com.yahoo.config.model.api.container.ContainerServiceType;
import com.yahoo.config.model.producer.AbstractConfigProducer;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
-import com.yahoo.container.handler.ThreadpoolConfig;
import com.yahoo.osgi.provider.model.ComponentModel;
import com.yahoo.prelude.fastsearch.FS4ResourcePool;
import com.yahoo.search.config.QrStartConfig;
@@ -15,10 +15,7 @@ import com.yahoo.vespa.model.container.component.Component;
*
* @author gjoranv
*/
-public final class ApplicationContainer extends Container implements
- QrStartConfig.Producer,
- ThreadpoolConfig.Producer
-{
+public final class ApplicationContainer extends Container implements QrStartConfig.Producer {
private static final String defaultHostedJVMArgs = "-XX:+UseOSErrorReporting -XX:+SuppressFatalErrorMessage";
@@ -44,9 +41,9 @@ public final class ApplicationContainer extends Container implements
@Override
public void getConfig(QrStartConfig.Builder builder) {
if (getHostResource() != null) {
- if ( ! getHostResource().realResources().isUnspecified()) {
- NodeResourcesTuning flavorTuning = new NodeResourcesTuning(getHostResource().realResources());
- flavorTuning.getConfig(builder);
+ NodeResources nodeResources = getHostResource().realResources();
+ if ( ! nodeResources.isUnspecified()) {
+ builder.jvm.availableProcessors(Math.max(2, (int)Math.ceil(nodeResources.vcpu())));
}
}
}
@@ -75,17 +72,4 @@ public final class ApplicationContainer extends Container implements
private boolean hasDocproc() {
return (parent instanceof ContainerCluster) && (((ContainerCluster)parent).getDocproc() != null);
}
-
- @Override
- public void getConfig(ThreadpoolConfig.Builder builder) {
- if (! (parent instanceof ContainerCluster)) return;
- if ((getHostResource() == null) || getHostResource().realResources().isUnspecified()) return;
- ContainerCluster containerCluster = (ContainerCluster) parent;
- if (containerCluster.getThreadPoolSizeFactor() <= 0.0) return;
-
- NodeResourcesTuning resourcesTuning = new NodeResourcesTuning(getHostResource().realResources())
- .setThreadPoolSizeFactor(containerCluster.getThreadPoolSizeFactor())
- .setQueueSizeFactor(containerCluster.getQueueSizeFactor());
- resourcesTuning.getConfig(builder);
- }
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index 6d8f3056cef..87e8f16f88c 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -160,17 +160,11 @@ public abstract class ContainerCluster<CONTAINER extends Container>
private String jvmGCOptions = null;
private String environmentVars = null;
- private final double threadPoolSizeFactor;
- private final double queueSizeFactor;
-
-
public ContainerCluster(AbstractConfigProducer<?> parent, String subId, String name, DeployState deployState) {
super(parent, subId);
this.name = name;
this.isHostedVespa = stateIsHosted(deployState);
this.zone = (deployState != null) ? deployState.zone() : Zone.defaultZone();
- this.threadPoolSizeFactor = deployState.getProperties().threadPoolSizeFactor();
- this.queueSizeFactor = deployState.getProperties().queueSizeFactor();
componentGroup = new ComponentGroup<>(this, "component");
@@ -192,14 +186,6 @@ public abstract class ContainerCluster<CONTAINER extends Container>
addJaxProviders();
}
- public double getThreadPoolSizeFactor() {
- return threadPoolSizeFactor;
- }
-
- public double getQueueSizeFactor() {
- return queueSizeFactor;
- }
-
public void setZone(Zone zone) {
this.zone = zone;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java
new file mode 100644
index 00000000000..c4d252ccbfe
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerThreadpool.java
@@ -0,0 +1,86 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.container;
+
+import com.yahoo.container.bundle.BundleInstantiationSpecification;
+import com.yahoo.container.handler.threadpool.ContainerThreadPool;
+import com.yahoo.container.handler.threadpool.ContainerThreadpoolConfig;
+import com.yahoo.osgi.provider.model.ComponentModel;
+import com.yahoo.text.XML;
+import com.yahoo.vespa.model.container.component.SimpleComponent;
+import org.w3c.dom.Element;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * Component definition for a {@link java.util.concurrent.Executor} using {@link ContainerThreadPool}.
+ *
+ * @author bjorncs
+ */
+public class ContainerThreadpool extends SimpleComponent implements ContainerThreadpoolConfig.Producer {
+
+ private final String name;
+ private final UserOptions userOptions;
+
+ public ContainerThreadpool(String name) { this(name, null); }
+
+ public ContainerThreadpool(String name, UserOptions userOptions) {
+ super(new ComponentModel(
+ BundleInstantiationSpecification.getFromStrings(
+ "threadpool@" + name,
+ ContainerThreadPool.class.getName(),
+ null)));
+ this.name = name;
+ this.userOptions = userOptions;
+ }
+
+ @Override
+ public void getConfig(ContainerThreadpoolConfig.Builder builder) {
+ builder.name(this.name);
+ if (userOptions != null) {
+ builder.maxThreads(userOptions.maxThreads);
+ builder.minThreads(userOptions.minThreads);
+ builder.queueSize(userOptions.queueSize);
+ }
+ }
+
+ protected Optional<UserOptions> userOptions() { return Optional.ofNullable(userOptions); }
+ protected boolean hasUserOptions() { return userOptions().isPresent(); }
+
+ protected static double vcpu(ContainerCluster<?> cluster) {
+ List<Double> vcpus = cluster.getContainers().stream()
+ .filter(c -> c.getHostResource() != null && c.getHostResource().realResources() != null)
+ .map(c -> c.getHostResource().realResources().vcpu())
+ .distinct()
+ .collect(Collectors.toList());
+ // We can only use host resource for calculation if all container nodes in the cluster are homogeneous (in terms of vcpu)
+ if (vcpus.size() != 1 || vcpus.get(0) == 0) return 0;
+ return vcpus.get(0);
+ }
+
+ public static class UserOptions {
+ private final int maxThreads;
+ private final int minThreads;
+ private final int queueSize;
+
+ private UserOptions(int maxThreads, int minThreads, int queueSize) {
+ this.maxThreads = maxThreads;
+ this.minThreads = minThreads;
+ this.queueSize = queueSize;
+ }
+
+ public static Optional<UserOptions> fromXml(Element xml) {
+ Element element = XML.getChild(xml, "threadpool");
+ if (element == null) return Optional.empty();
+ return Optional.of(new UserOptions(
+ intOption(element, "max-threads"),
+ intOption(element, "min-threads"),
+ intOption(element, "queue-size")));
+ }
+
+ private static int intOption(Element element, String name) {
+ return Integer.parseInt(XML.getChild(element, name).getTextContent());
+ }
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/NodeResourcesTuning.java b/config-model/src/main/java/com/yahoo/vespa/model/container/NodeResourcesTuning.java
deleted file mode 100644
index 7eb7a1fb518..00000000000
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/NodeResourcesTuning.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.model.container;
-
-import com.yahoo.config.provision.NodeResources;
-import com.yahoo.container.handler.ThreadpoolConfig;
-import com.yahoo.search.config.QrStartConfig;
-
-/**
- * Tuning of qr-start config for a container service based on node resources.
- *
- * @author balder
- */
-public class NodeResourcesTuning implements QrStartConfig.Producer, ThreadpoolConfig.Producer {
-
- private final NodeResources resources;
-
- public NodeResourcesTuning setThreadPoolSizeFactor(double threadPoolSizeFactor) {
- this.threadPoolSizeFactor = threadPoolSizeFactor;
- return this;
- }
-
- public NodeResourcesTuning setQueueSizeFactor(double queueSizeFactor) {
- this.queueSizeFactor = queueSizeFactor;
- return this;
- }
-
- private double threadPoolSizeFactor = 8.0;
- private double queueSizeFactor = 8.0;
-
- NodeResourcesTuning(NodeResources resources) {
- this.resources = resources;
- }
-
- @Override
- public void getConfig(QrStartConfig.Builder builder) {
- builder.jvm.availableProcessors(Math.max(2, (int)Math.ceil(resources.vcpu())));
- }
-
- @Override
- public void getConfig(ThreadpoolConfig.Builder builder) {
- // Controls max number of concurrent requests per container
- int workerThreads = Math.max(2, (int)Math.ceil(resources.vcpu() * threadPoolSizeFactor));
- builder.maxthreads(workerThreads);
-
- // This controls your burst handling capability.
- // 0 => No extra burst handling beyond you max concurrent requests (maxthreads).
- // N => N times max concurrent requests as a buffer for handling bursts
- builder.queueSize((int)(workerThreads * queueSizeFactor));
- }
-}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ThreadPoolExecutorComponent.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ThreadPoolExecutorComponent.java
deleted file mode 100644
index 9d59941f603..00000000000
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ThreadPoolExecutorComponent.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.model.container;
-
-import com.yahoo.container.bundle.BundleInstantiationSpecification;
-import com.yahoo.container.handler.threadpool.ContainerThreadPool;
-import com.yahoo.container.handler.threadpool.ContainerThreadpoolConfig;
-import com.yahoo.osgi.provider.model.ComponentModel;
-import com.yahoo.vespa.model.container.component.SimpleComponent;
-
-import java.time.Duration;
-
-/**
- * Component definition for a {@link java.util.concurrent.Executor} using {@link ContainerThreadPool}.
- *
- * @author bjorncs
- */
-public class ThreadPoolExecutorComponent extends SimpleComponent implements ContainerThreadpoolConfig.Producer {
-
- private final String name;
- private final Integer maxPoolSize;
- private final Integer corePoolSize;
- private final Duration keepAliveTime;
- private final Integer queueSize;
- private final Duration maxThreadExecutionTime;
-
- private ThreadPoolExecutorComponent(Builder builder) {
- super(new ComponentModel(
- BundleInstantiationSpecification.getFromStrings(
- "threadpool@" + builder.name,
- ContainerThreadPool.class.getName(),
- null)));
- this.name = builder.name;
- this.maxPoolSize = builder.maxPoolSize;
- this.corePoolSize = builder.corePoolSize;
- this.keepAliveTime = builder.keepAliveTime;
- this.queueSize = builder.queueSize;
- this.maxThreadExecutionTime = builder.maxThreadExecutionTime;
- }
-
- @Override
- public void getConfig(ContainerThreadpoolConfig.Builder builder) {
- builder.name(this.name);
- if (maxPoolSize != null) builder.maxThreads(maxPoolSize);
- if (corePoolSize != null) builder.minThreads(corePoolSize);
- if (keepAliveTime != null) builder.keepAliveTime(keepAliveTime.toMillis() / 1000D);
- if (queueSize != null) builder.queueSize(queueSize);
- if (maxThreadExecutionTime != null) builder.maxThreadExecutionTimeSeconds((int)maxThreadExecutionTime.toMillis() / 1000);
- }
-
- public static class Builder {
-
- private final String name;
- private Integer maxPoolSize;
- private Integer corePoolSize;
- private Duration keepAliveTime;
- private Integer queueSize;
- private Duration maxThreadExecutionTime;
-
- public Builder(String name) { this.name = name; }
-
- public Builder maxPoolSize(int size) { this.maxPoolSize = size; return this; }
- public Builder corePoolSize(int size) { this.corePoolSize = size; return this; }
- public Builder keepAliveTime(Duration time) { this.keepAliveTime = time; return this; }
- public Builder queueSize(int size) { this.queueSize = size; return this; }
- public Builder maxThreadExecutionTime(Duration time) { this.maxThreadExecutionTime = time; return this; }
-
- public ThreadPoolExecutorComponent build() { return new ThreadPoolExecutorComponent(this); }
-
- }
-}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/BundleInstantiationSpecificationBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/BundleInstantiationSpecificationBuilder.java
index 4e0bff1c1fc..12d74418f9f 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/BundleInstantiationSpecificationBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/BundleInstantiationSpecificationBuilder.java
@@ -9,8 +9,6 @@ import org.w3c.dom.Element;
import java.util.Arrays;
import java.util.List;
-import static com.yahoo.vespa.model.container.xml.ContainerModelBuilder.SEARCH_HANDLER_CLASS;
-
/**
* This object builds a bundle instantiation spec from an XML element.
*
@@ -39,7 +37,7 @@ public class BundleInstantiationSpecificationBuilder {
private static void validate(BundleInstantiationSpecification instSpec) {
List<String> forbiddenClasses = Arrays.asList(
- SEARCH_HANDLER_CLASS,
+ SearchHandler.HANDLER_CLASS,
"com.yahoo.processing.handler.ProcessingHandler");
for (String forbiddenClass: forbiddenClasses) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index 0e77c6387ae..638c02caf55 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -54,6 +54,7 @@ import com.yahoo.vespa.model.container.Container;
import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.ContainerModel;
import com.yahoo.vespa.model.container.ContainerModelEvaluation;
+import com.yahoo.vespa.model.container.ContainerThreadpool;
import com.yahoo.vespa.model.container.IdentityProvider;
import com.yahoo.vespa.model.container.SecretStore;
import com.yahoo.vespa.model.container.component.BindingPattern;
@@ -111,9 +112,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
private static final String DEPRECATED_CONTAINER_TAG = "jdisc";
private static final String ENVIRONMENT_VARIABLES_ELEMENT = "environment-variables";
- static final String SEARCH_HANDLER_CLASS = com.yahoo.search.handler.SearchHandler.class.getName();
- static final BindingPattern SEARCH_HANDLER_BINDING = SystemBindingPattern.fromHttpPath("/search/*");
-
public enum Networking { disable, enable }
private ApplicationPackage app;
@@ -197,7 +195,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
addClientProviders(deployState, spec, cluster);
addServerProviders(deployState, spec, cluster);
- addHandlerSpecificThreadpools(cluster);
addAthensCopperArgos(cluster, context); // Must be added after nodes.
}
@@ -212,13 +209,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
}
- private void addHandlerSpecificThreadpools(ContainerCluster<?> cluster) {
- ContainerDocumentApi documentApi = cluster.getDocumentApi();
- if (documentApi != null) {
- documentApi.addNodesDependentThreadpoolConfiguration();
- }
- }
-
private void addAthensCopperArgos(ApplicationContainerCluster cluster, ConfigModelContext context) {
if ( ! context.getDeployState().isHosted()) return;
app.getDeployment().map(DeploymentSpec::fromXml)
@@ -427,7 +417,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
addIncludes(searchElement);
cluster.setSearch(buildSearch(deployState, cluster, searchElement));
- addSearchHandler(cluster, searchElement);
+ addSearchHandler(cluster, searchElement, deployState);
addGUIHandler(cluster);
validateAndAddConfiguredComponents(deployState, cluster, searchElement, "renderer", ContainerModelBuilder::validateRendererElement);
}
@@ -447,7 +437,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
addIncludes(processingElement);
cluster.setProcessingChains(new DomProcessingBuilder(null).build(deployState, cluster, processingElement),
- serverBindings(processingElement, ProcessingChains.defaultBindings));
+ serverBindings(processingElement, ProcessingChains.defaultBindings).toArray(BindingPattern[]::new));
validateAndAddConfiguredComponents(deployState, cluster, processingElement, "renderer", ContainerModelBuilder::validateRendererElement);
}
@@ -791,19 +781,17 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
container.setPreLoad(nodesElement.getAttribute(VespaDomBuilder.PRELOAD_ATTRIB_NAME));
}
- private void addSearchHandler(ApplicationContainerCluster cluster, Element searchElement) {
+ private void addSearchHandler(ApplicationContainerCluster cluster, Element searchElement, DeployState deployState) {
// Magic spell is needed to receive the chains config :-|
cluster.addComponent(new ProcessingHandler<>(cluster.getSearch().getChains(),
"com.yahoo.search.searchchain.ExecutionFactory"));
- ProcessingHandler<SearchChains> searchHandler = new ProcessingHandler<>(cluster.getSearch().getChains(),
- "com.yahoo.search.handler.SearchHandler");
- BindingPattern[] defaultBindings = {SEARCH_HANDLER_BINDING};
- for (BindingPattern binding: serverBindings(searchElement, defaultBindings)) {
- searchHandler.addServerBindings(binding);
- }
-
- cluster.addComponent(searchHandler);
+ cluster.addComponent(
+ new SearchHandler(
+ cluster,
+ serverBindings(searchElement, SearchHandler.DEFAULT_BINDING),
+ ContainerThreadpool.UserOptions.fromXml(searchElement).orElse(null),
+ deployState));
}
private void addGUIHandler(ApplicationContainerCluster cluster) {
@@ -813,15 +801,15 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
- private BindingPattern[] serverBindings(Element searchElement, BindingPattern... defaultBindings) {
+ private List<BindingPattern> serverBindings(Element searchElement, BindingPattern... defaultBindings) {
List<Element> bindings = XML.getChildren(searchElement, "binding");
if (bindings.isEmpty())
- return defaultBindings;
+ return List.of(defaultBindings);
return toBindingList(bindings);
}
- private BindingPattern[] toBindingList(List<Element> bindingElements) {
+ private List<BindingPattern> toBindingList(List<Element> bindingElements) {
List<BindingPattern> result = new ArrayList<>();
for (Element element: bindingElements) {
@@ -830,7 +818,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
result.add(UserBindingPattern.fromPattern(text));
}
- return result.toArray(BindingPattern[]::new);
+ return result;
}
private ContainerDocumentApi buildDocumentApi(DeployState deployState, ApplicationContainerCluster cluster, Element spec) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java
index 34de21de404..99ae6184f5c 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/DocumentApiOptionsBuilder.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.model.container.xml;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.text.XML;
import com.yahoo.vespa.model.clients.ContainerDocumentApi;
+import com.yahoo.vespa.model.container.ContainerThreadpool;
import org.w3c.dom.Element;
import java.util.ArrayList;
@@ -20,7 +21,17 @@ public class DocumentApiOptionsBuilder {
public static ContainerDocumentApi.Options build(DeployState deployState, Element spec) {
- return new ContainerDocumentApi.Options(getBindings(spec), deployState.getProperties().feedCoreThreadPoolSizeFactor());
+ return new ContainerDocumentApi.Options(
+ getBindings(spec),
+ threadpoolOptions(spec, "rest-api"),
+ threadpoolOptions(spec, "http-client-api"),
+ deployState.getProperties().feedCoreThreadPoolSizeFactor());
+ }
+
+ private static ContainerThreadpool.UserOptions threadpoolOptions(Element spec, String elementName) {
+ Element element = XML.getChild(spec, elementName);
+ if (element == null) return null;
+ return ContainerThreadpool.UserOptions.fromXml(element).orElse(null);
}
private static List<String> getBindings(Element spec) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java
new file mode 100644
index 00000000000..81ab2cc1503
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/SearchHandler.java
@@ -0,0 +1,80 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.container.xml;
+
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.container.handler.threadpool.ContainerThreadpoolConfig;
+import com.yahoo.vespa.model.container.ApplicationContainerCluster;
+import com.yahoo.vespa.model.container.ContainerThreadpool;
+import com.yahoo.vespa.model.container.component.BindingPattern;
+import com.yahoo.vespa.model.container.component.SystemBindingPattern;
+import com.yahoo.vespa.model.container.component.chain.ProcessingHandler;
+import com.yahoo.vespa.model.container.search.searchchain.SearchChains;
+
+import java.util.List;
+
+/**
+ * Component definition for {@link com.yahoo.search.handler.SearchHandler}
+ *
+ * @author bjorncs
+ */
+class SearchHandler extends ProcessingHandler<SearchChains> {
+
+ static final String HANDLER_CLASS = com.yahoo.search.handler.SearchHandler.class.getName();
+ static final BindingPattern DEFAULT_BINDING = SystemBindingPattern.fromHttpPath("/search/*");
+
+ private final ApplicationContainerCluster cluster;
+
+ SearchHandler(ApplicationContainerCluster cluster,
+ List<BindingPattern> bindings,
+ ContainerThreadpool.UserOptions threadpoolOptions,
+ DeployState deployState) {
+ super(cluster.getSearchChains(), HANDLER_CLASS);
+ this.cluster = cluster;
+ bindings.forEach(this::addServerBindings);
+ Threadpool threadpool = new Threadpool(cluster, threadpoolOptions, deployState);
+ inject(threadpool);
+ addComponent(threadpool);
+ }
+
+ private static class Threadpool extends ContainerThreadpool {
+ private final ApplicationContainerCluster cluster;
+ private final DeployState deployState;
+
+ Threadpool(ApplicationContainerCluster cluster, UserOptions options, DeployState deployState) {
+ super("search-handler", options);
+ this.cluster = cluster;
+ this.deployState = deployState;
+ }
+
+ @Override
+ public void getConfig(ContainerThreadpoolConfig.Builder builder) {
+ super.getConfig(builder);
+
+ builder.maxThreadExecutionTimeSeconds(190);
+ builder.keepAliveTime(5.0);
+
+ // User options overrides below configuration
+ if (hasUserOptions()) return;
+
+ double threadPoolSizeFactor = deployState.getProperties().threadPoolSizeFactor();
+ double vcpu = vcpu(cluster);
+ if (threadPoolSizeFactor <= 0 || vcpu == 0) {
+ builder.maxThreads(500);
+ builder.minThreads(500);
+ builder.queueSize(0);
+ } else {
+ // Controls max number of concurrent requests per container
+ int workerThreads = Math.max(2, (int)Math.ceil(vcpu * threadPoolSizeFactor));
+ builder.maxThreads(workerThreads);
+ builder.minThreads(workerThreads);
+
+ // This controls your burst handling capability.
+ // 0 => No extra burst handling beyond you max concurrent requests (maxthreads).
+ // N => N times max concurrent requests as a buffer for handling bursts
+ builder.queueSize((int)(workerThreads * deployState.getProperties().queueSizeFactor()));
+ }
+ }
+
+
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java
index f2e90ae2859..34b6dd017cf 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java
@@ -27,6 +27,7 @@ public abstract class ContentNode extends AbstractService
private final boolean skipCommunicationManagerThread;
private final boolean skipMbusRequestThread;
private final boolean skipMbusReplyThread;
+ private final boolean useDirectStorageApiRpc;
public ContentNode(ModelContext.Properties properties, AbstractConfigProducer parent, String clusterName, String rootDirectory, int distributionKey) {
super(parent, "" + distributionKey);
@@ -35,6 +36,7 @@ public abstract class ContentNode extends AbstractService
this.skipMbusRequestThread = properties.skipMbusRequestThread();
this.skipMbusReplyThread = properties.skipMbusReplyThread();
this.rootDirectory = rootDirectory;
+ this.useDirectStorageApiRpc = properties.useDirectStorageApiRpc();
initialize();
setProp("clustertype", "content");
@@ -81,6 +83,7 @@ public abstract class ContentNode extends AbstractService
builder.skip_thread(skipCommunicationManagerThread);
builder.mbus.skip_request_thread(skipMbusRequestThread);
builder.mbus.skip_reply_thread(skipMbusReplyThread);
+ builder.use_direct_storageapi_rpc(useDirectStorageApiRpc);
}
@Override
diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc
index 3c8b60fb84b..98ea696ceef 100644
--- a/config-model/src/main/resources/schema/containercluster.rnc
+++ b/config-model/src/main/resources/schema/containercluster.rnc
@@ -105,6 +105,12 @@ SslProvider = element ssl-provider {
BundleSpec
}
+Threadpool = element threadpool {
+ element max-threads { xsd:nonNegativeInteger } &
+ element min-threads { xsd:nonNegativeInteger } &
+ element queue-size { xsd:nonNegativeInteger }
+}
+
# REST-API:
RestApi = element rest-api {
@@ -142,7 +148,8 @@ SearchInContainer = element search {
SearchChain* &
Provider* &
Renderer* &
- GenericConfig*
+ GenericConfig* &
+ Threadpool?
}
SearchChain = element chain {
@@ -207,10 +214,18 @@ DocumentApi = element document-api {
element retrydelay { xsd:double { minInclusive = "0.0" } }? &
element timeout { xsd:double { minInclusive = "0.0" } }? &
element tracelevel { xsd:positiveInteger }? &
- element mbusport { xsd:positiveInteger }?
+ element mbusport { xsd:positiveInteger }? &
+ DocumentRestApi? &
+ HttpClientApi?
}
+DocumentRestApi = element rest-api {
+ Threadpool?
+}
+HttpClientApi = element http-client-api {
+ Threadpool?
+}
# NODES:
diff --git a/config-model/src/main/resources/schema/federation.rnc b/config-model/src/main/resources/schema/federation.rnc
index 6dbeb32fbb2..227bebc16ba 100644
--- a/config-model/src/main/resources/schema/federation.rnc
+++ b/config-model/src/main/resources/schema/federation.rnc
@@ -16,6 +16,8 @@ Provider =
attribute cachesize { xsd:string { pattern = "\d+(\.\d*)?\s*[kmgKMG]?" } }? &
attribute type { xsd:string }? &
attribute cluster { xsd:string }? &
+
+ # TODO Vespa 8 Remove yca concepts from services.xml syntax
attribute yca-application-id { xsd:string }? &
attribute yca-cache-ttl { xsd:string { pattern = "\d+(\.\d*)?\s*m?s" } }? &
attribute yca-cache-retry-wait { xsd:string { pattern = "\d+(\.\d*)?\s*m?s" } }? &
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
index be7fc19a429..71dc1564277 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
@@ -87,7 +87,7 @@ public class DedicatedAdminV4Test {
MetricsConsumer consumer = model.getAdmin().getUserMetrics().getConsumers().get("slingstone");
assertNotNull(consumer);
- Metric metric = consumer.getMetrics().get("foobar.count");
+ Metric metric = consumer.metrics().get("foobar.count");
assertNotNull(metric);
assertEquals("foobar", metric.outputName);
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsConsumersTest.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsConsumersTest.java
index 12a10a7e354..36eb30073b3 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsConsumersTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsConsumersTest.java
@@ -4,6 +4,7 @@ import ai.vespa.metricsproxy.core.ConsumersConfig;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.admin.monitoring.Metric;
import com.yahoo.vespa.model.admin.monitoring.MetricSet;
+import com.yahoo.vespa.model.admin.monitoring.MetricsConsumer;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -16,13 +17,11 @@ import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyModelTester.c
import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyModelTester.getCustomConsumer;
import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyModelTester.getModel;
import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyModelTester.servicesWithAdminOnly;
-import static com.yahoo.vespa.model.admin.monitoring.DefaultPublicConsumer.DEFAULT_PUBLIC_CONSUMER_ID;
-import static com.yahoo.vespa.model.admin.monitoring.DefaultPublicMetrics.defaultPublicMetricSet;
+import static com.yahoo.vespa.model.admin.monitoring.DefaultMetrics.defaultMetricSet;
import static com.yahoo.vespa.model.admin.monitoring.DefaultVespaMetrics.defaultVespaMetricSet;
import static com.yahoo.vespa.model.admin.monitoring.NetworkMetrics.networkMetricSet;
import static com.yahoo.vespa.model.admin.monitoring.SystemMetrics.systemMetricSet;
import static com.yahoo.vespa.model.admin.monitoring.VespaMetricSet.vespaMetricSet;
-import static com.yahoo.vespa.model.admin.monitoring.VespaMetricsConsumer.VESPA_CONSUMER_ID;
import static java.util.Collections.singleton;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -34,7 +33,7 @@ import static org.junit.Assert.assertTrue;
*/
public class MetricsConsumersTest {
- private static int numPublicDefaultMetrics = defaultPublicMetricSet.getMetrics().size();
+ private static int numPublicDefaultMetrics = defaultMetricSet.getMetrics().size();
private static int numDefaultVespaMetrics = defaultVespaMetricSet.getMetrics().size();
private static int numVespaMetrics = vespaMetricSet.getMetrics().size();
private static int numSystemMetrics = systemMetricSet.getMetrics().size();
@@ -48,9 +47,9 @@ public class MetricsConsumersTest {
public void default_public_consumer_is_set_up_for_self_hosted() {
ConsumersConfig config = consumersConfigFromXml(servicesWithAdminOnly(), self_hosted);
assertEquals(2, config.consumer().size());
- assertEquals(config.consumer(1).name(), DEFAULT_PUBLIC_CONSUMER_ID);
+ assertEquals(MetricsConsumer.defaultConsumer.id(), config.consumer(1).name());
- int numMetricsForPublicDefaultConsumer = defaultPublicMetricSet.getMetrics().size() + numSystemMetrics;
+ int numMetricsForPublicDefaultConsumer = defaultMetricSet.getMetrics().size() + numSystemMetrics;
assertEquals(numMetricsForPublicDefaultConsumer, config.consumer(1).metric().size());
}
@@ -58,14 +57,14 @@ public class MetricsConsumersTest {
public void vespa_consumer_and_default_public_consumer_is_set_up_for_hosted() {
ConsumersConfig config = consumersConfigFromXml(servicesWithAdminOnly(), hosted);
assertEquals(2, config.consumer().size());
- assertEquals(config.consumer(0).name(), VESPA_CONSUMER_ID);
- assertEquals(config.consumer(1).name(), DEFAULT_PUBLIC_CONSUMER_ID);
+ assertEquals(MetricsConsumer.vespa.id(), config.consumer(0).name());
+ assertEquals(MetricsConsumer.defaultConsumer.id(), config.consumer(1).name());
}
@Test
public void vespa_consumer_is_always_present_and_has_all_vespa_metrics_and_all_system_metrics() {
ConsumersConfig config = consumersConfigFromXml(servicesWithAdminOnly(), self_hosted);
- assertEquals(config.consumer(0).name(), VESPA_CONSUMER_ID);
+ assertEquals(MetricsConsumer.vespa.id(), config.consumer(0).name());
assertEquals(numMetricsForVespaConsumer, config.consumer(0).metric().size());
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java
index 8ecb13d7ae5..b6037d2614e 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java
@@ -14,12 +14,11 @@ import ai.vespa.metricsproxy.service.VespaServicesConfig;
import com.yahoo.search.config.QrStartConfig;
import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.admin.monitoring.Metric;
+import com.yahoo.vespa.model.admin.monitoring.MetricsConsumer;
import com.yahoo.vespa.model.test.VespaModelTester;
import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyModelTester.TestMode.hosted;
import static com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyModelTester.TestMode.self_hosted;
-import static com.yahoo.vespa.model.admin.monitoring.DefaultPublicConsumer.DEFAULT_PUBLIC_CONSUMER_ID;
-import static com.yahoo.vespa.model.admin.monitoring.VespaMetricsConsumer.VESPA_CONSUMER_ID;
/**
* @author gjoranv
@@ -76,7 +75,8 @@ class MetricsProxyModelTester {
static ConsumersConfig.Consumer getCustomConsumer(String servicesXml) {
ConsumersConfig config = consumersConfigFromXml(servicesXml, self_hosted);
for (ConsumersConfig.Consumer consumer : config.consumer()) {
- if (! consumer.name().equals(VESPA_CONSUMER_ID) && ! consumer.name().equals(DEFAULT_PUBLIC_CONSUMER_ID))
+ if (! consumer.name().equals(MetricsConsumer.vespa.id()) &&
+ ! consumer.name().equals(MetricsConsumer.defaultConsumer.id()))
return consumer;
}
throw new RuntimeException("Custom consumer not found!");
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
index 97359b392a5..d493afd9c1f 100755
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
@@ -10,11 +10,9 @@ import com.yahoo.config.model.deploy.TestProperties;
import com.yahoo.config.model.test.MockRoot;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
-import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
-import com.yahoo.config.provisioning.FlavorsConfig;
import com.yahoo.container.di.config.PlatformBundlesConfig;
import com.yahoo.container.handler.ThreadpoolConfig;
import com.yahoo.search.config.QrStartConfig;
@@ -230,20 +228,6 @@ public class ContainerClusterTest {
}
@Test
- public void requireThatPoolAndQueueCanBeControlledByPropertiesAndFlavor() {
- FlavorsConfig.Flavor.Builder flavorBuilder = new FlavorsConfig.Flavor.Builder().name("my_flavor").minCpuCores(3);
- NodeResourcesTuning nodeResourcesTuning = new NodeResourcesTuning(new Flavor(new FlavorsConfig.Flavor(flavorBuilder)).resources())
- .setThreadPoolSizeFactor(13.3)
- .setQueueSizeFactor(17.5);
-
- ThreadpoolConfig.Builder tpBuilder = new ThreadpoolConfig.Builder();
- nodeResourcesTuning.getConfig(tpBuilder);
- ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
- assertEquals(40, threadpoolConfig.maxthreads());
- assertEquals(700, threadpoolConfig.queueSize());
- }
-
- @Test
public void requireThatDefaultThreadPoolConfigIsSane() {
MockRoot root = new MockRoot("foo");
ApplicationContainerCluster cluster = createContainerCluster(root, false);
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
index 93117821c5a..def5da3a9c2 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
@@ -121,6 +121,43 @@ public class ContainerDocumentApiBuilderTest extends ContainerModelBuilderTestBa
assertEquals(8, config.minThreads());
}
+ @Test
+ public void threadpools_configuration_can_be_overridden() {
+ Element elem = DomBuilderTest.parse(
+ "<container id='cluster1' version='1.0'>",
+ " <document-api>",
+ " <rest-api>",
+ " <threadpool>",
+ " <max-threads>20</max-threads>",
+ " <min-threads>10</min-threads>",
+ " <queue-size>0</queue-size>",
+ " </threadpool>",
+ " </rest-api>",
+ " <http-client-api>",
+ " <threadpool>",
+ " <max-threads>50</max-threads>",
+ " <min-threads>25</min-threads>",
+ " <queue-size>1000</queue-size>",
+ " </threadpool>",
+ " </http-client-api>",
+ " </document-api>",
+ nodesXml,
+ "</container>");
+ createModel(root, elem);
+
+ ContainerThreadpoolConfig restApiThreadpoolConfig = root.getConfig(
+ ContainerThreadpoolConfig.class, "cluster1/component/com.yahoo.document.restapi.resource.RestApi/threadpool@restapi-handler");
+ assertEquals(20, restApiThreadpoolConfig.maxThreads());
+ assertEquals(10, restApiThreadpoolConfig.minThreads());
+ assertEquals(0, restApiThreadpoolConfig.queueSize());
+
+ ContainerThreadpoolConfig feedThreadpoolConfig = root.getConfig(
+ ContainerThreadpoolConfig.class, "cluster1/component/com.yahoo.vespa.http.server.FeedHandler/threadpool@feedapi-handler");
+ assertEquals(50, feedThreadpoolConfig.maxThreads());
+ assertEquals(25, feedThreadpoolConfig.minThreads());
+ assertEquals(1000, feedThreadpoolConfig.queueSize());
+ }
+
private static class HostProvisionerWithCustomRealResource implements HostProvisioner {
@Override
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/SearchBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/SearchBuilderTest.java
index c8564c5a273..4c1fda44038 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/SearchBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/SearchBuilderTest.java
@@ -4,10 +4,11 @@ package com.yahoo.vespa.model.container.xml;
import com.yahoo.component.ComponentId;
import com.yahoo.config.model.builder.xml.test.DomBuilderTest;
import com.yahoo.container.core.ChainsConfig;
+import com.yahoo.container.handler.threadpool.ContainerThreadpoolConfig;
import com.yahoo.container.jdisc.JdiscBindingsConfig;
import com.yahoo.vespa.model.VespaModel;
-import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.ApplicationContainerCluster;
+import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.component.Handler;
import com.yahoo.vespa.model.container.search.GUIHandler;
import com.yahoo.vespa.model.test.utils.ApplicationPackageUtils;
@@ -18,9 +19,8 @@ import org.w3c.dom.Element;
import static com.yahoo.config.model.api.container.ContainerServiceType.QRSERVER;
import static com.yahoo.test.Matchers.hasItemWithMethod;
import static com.yahoo.vespa.model.container.search.ContainerSearch.QUERY_PROFILE_REGISTRY_CLASS;
-import static com.yahoo.vespa.model.container.xml.ContainerModelBuilder.SEARCH_HANDLER_BINDING;
-import static com.yahoo.vespa.model.container.xml.ContainerModelBuilder.SEARCH_HANDLER_CLASS;
import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -105,7 +105,7 @@ public class SearchBuilderTest extends ContainerModelBuilderTestBase {
"<container id='default' version='1.0'>",
" <search />",
" <handler id='" + myHandler + "'>",
- " <binding>" + SEARCH_HANDLER_BINDING.patternString() + "</binding>",
+ " <binding>" + SearchHandler.DEFAULT_BINDING.patternString() + "</binding>",
" </handler>",
nodesXml,
"</container>");
@@ -113,8 +113,8 @@ public class SearchBuilderTest extends ContainerModelBuilderTestBase {
createModel(root, clusterElem);
var discBindingsConfig = root.getConfig(JdiscBindingsConfig.class, "default");
- assertEquals(SEARCH_HANDLER_BINDING.patternString(), discBindingsConfig.handlers(myHandler).serverBindings(0));
- assertNull(discBindingsConfig.handlers(SEARCH_HANDLER_CLASS));
+ assertEquals(SearchHandler.DEFAULT_BINDING.patternString(), discBindingsConfig.handlers(myHandler).serverBindings(0));
+ assertNull(discBindingsConfig.handlers(SearchHandler.HANDLER_CLASS));
}
// TODO: remove test when all containers are named 'container'
@@ -222,6 +222,51 @@ public class SearchBuilderTest extends ContainerModelBuilderTestBase {
assertFalse(cluster.getSearchChains().localProviders().isEmpty());
}
+ @Test
+ public void search_handler_has_dedicated_threadpool() {
+ Element clusterElem = DomBuilderTest.parse(
+ "<container id='default' version='1.0'>",
+ " <search />",
+ nodesXml,
+ "</container>");
+
+ createModel(root, clusterElem);
+
+ ApplicationContainerCluster cluster = (ApplicationContainerCluster)root.getChildren().get("default");
+ Handler<?> searchHandler = cluster.getHandlers().stream()
+ .filter(h -> h.getComponentId().toString().equals(SearchHandler.HANDLER_CLASS))
+ .findAny()
+ .get();
+
+ assertThat(searchHandler.getInjectedComponentIds(), hasItem("threadpool@search-handler"));
+
+ ContainerThreadpoolConfig config = root.getConfig(
+ ContainerThreadpoolConfig.class, "default/component/" + SearchHandler.HANDLER_CLASS + "/threadpool@search-handler");
+ assertEquals(500, config.maxThreads());
+ assertEquals(500, config.minThreads());
+ assertEquals(0, config.queueSize());
+ }
+
+ @Test
+ public void threadpool_configuration_can_be_overridden() {
+ Element clusterElem = DomBuilderTest.parse(
+ "<container id='default' version='1.0'>",
+ " <search>",
+ " <threadpool>",
+ " <max-threads>100</max-threads>",
+ " <min-threads>80</min-threads>",
+ " <queue-size>10</queue-size>",
+ " </threadpool>",
+ " </search>",
+ nodesXml,
+ "</container>");
+ createModel(root, clusterElem);
+ ContainerThreadpoolConfig config = root.getConfig(
+ ContainerThreadpoolConfig.class, "default/component/" + SearchHandler.HANDLER_CLASS + "/threadpool@search-handler");
+ assertEquals(100, config.maxThreads());
+ assertEquals(80, config.minThreads());
+ assertEquals(10, config.queueSize());
+ }
private VespaModel getVespaModelWithMusic(String hosts, String services) {
return new VespaModelCreatorWithMockPkg(hosts, services, ApplicationPackageUtils.generateSchemas("music")).create();
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java
index 27c88ad2d1f..61f5ec56bb4 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java
@@ -16,6 +16,7 @@ import com.yahoo.vespa.config.content.AllClustersBucketSpacesConfig;
import com.yahoo.vespa.config.content.FleetcontrollerConfig;
import com.yahoo.vespa.config.content.StorDistributionConfig;
import com.yahoo.vespa.config.content.StorFilestorConfig;
+import com.yahoo.vespa.config.content.core.StorCommunicationmanagerConfig;
import com.yahoo.vespa.config.content.core.StorDistributormanagerConfig;
import com.yahoo.vespa.config.content.core.StorServerConfig;
import com.yahoo.vespa.config.search.DispatchConfig;
@@ -980,4 +981,31 @@ public class ContentClusterTest extends ContentBaseTest {
assertTrue(resolveThreePhaseUpdateConfigWithFeatureFlag(true));
}
+ void assertDirectStorageApiRpcConfig(boolean expUseDirectStorageApiRpc, ContentNode node) {
+ var builder = new StorCommunicationmanagerConfig.Builder();
+ node.getConfig(builder);
+ var config = new StorCommunicationmanagerConfig(builder);
+ assertEquals(expUseDirectStorageApiRpc, config.use_direct_storageapi_rpc());
+ }
+
+ void assertDirectStorageApiRpcFlagIsPropagatedToConfig(boolean useDirectStorageApiRpc) {
+ VespaModel model = createEnd2EndOneNode(new TestProperties().setUseDirectStorageApiRpc(useDirectStorageApiRpc));
+
+ ContentCluster cc = model.getContentClusters().get("storage");
+ assertFalse(cc.getDistributorNodes().getChildren().isEmpty());
+ for (Distributor d : cc.getDistributorNodes().getChildren().values()) {
+ assertDirectStorageApiRpcConfig(useDirectStorageApiRpc, d);
+ }
+ assertFalse(cc.getStorageNodes().getChildren().isEmpty());
+ for (StorageNode node : cc.getStorageNodes().getChildren().values()) {
+ assertDirectStorageApiRpcConfig(useDirectStorageApiRpc, node);
+ }
+ }
+
+ @Test
+ public void use_direct_storage_api_rpc_config_is_controlled_by_properties() {
+ assertDirectStorageApiRpcFlagIsPropagatedToConfig(false);
+ assertDirectStorageApiRpcFlagIsPropagatedToConfig(true);
+ }
+
}
diff --git a/config-model/src/test/schema-test-files/services.xml b/config-model/src/test/schema-test-files/services.xml
index e7ea2683e3f..683e2dc0b0d 100644
--- a/config-model/src/test/schema-test-files/services.xml
+++ b/config-model/src/test/schema-test-files/services.xml
@@ -158,6 +158,20 @@
<timeout>5.55</timeout>
<route>default</route>
<maxpendingdocs>100</maxpendingdocs>
+ <rest-api>
+ <threadpool>
+ <max-threads>50</max-threads>
+ <min-threads>10</min-threads>
+ <queue-size>1000</queue-size>
+ </threadpool>
+ </rest-api>
+ <http-client-api>
+ <threadpool>
+ <max-threads>50</max-threads>
+ <min-threads>10</min-threads>
+ <queue-size>1000</queue-size>
+ </threadpool>
+ </http-client-api>
</document-api>
<search>
@@ -184,6 +198,12 @@
</chain>
<chain id="achain" searchers="asearcher anothersearcher" inherits="wonkaparentchain" excludes="notneededsearcher"/>
+
+ <threadpool>
+ <max-threads>500</max-threads>
+ <min-threads>500</min-threads>
+ <queue-size>0</queue-size>
+ </threadpool>
</search>
<processing>