diff options
40 files changed, 482 insertions, 113 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f077dd87b9d..ab79c607cab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,6 +120,7 @@ add_subdirectory(container-core) add_subdirectory(container-disc) add_subdirectory(container-messagebus) add_subdirectory(container-onnxruntime) +add_subdirectory(container-llama) add_subdirectory(container-search) add_subdirectory(container-search-and-docproc) add_subdirectory(container-spifly) diff --git a/client/js/app/yarn.lock b/client/js/app/yarn.lock index 28313d7fb65..1023b9adb5c 100644 --- a/client/js/app/yarn.lock +++ b/client/js/app/yarn.lock @@ -830,31 +830,31 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.4.tgz#19654d1026cc410975d46445180e70a5089b3e7d" integrity sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA== -"@fortawesome/fontawesome-common-types@6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz#fdb1ec4952b689f5f7aa0bffe46180bb35490032" - integrity sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A== +"@fortawesome/fontawesome-common-types@6.5.2": + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz#eaf2f5699f73cef198454ebc0c414e3688898179" + integrity sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw== "@fortawesome/fontawesome-svg-core@^6": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz#9d56d46bddad78a7ebb2043a97957039fcebcf0a" - integrity sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ== + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz#4b42de71e196039b0d5ccf88559b8044e3296c21" + integrity sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.1" + "@fortawesome/fontawesome-common-types" "6.5.2" "@fortawesome/free-regular-svg-icons@^6": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz#c98a91d2c9137ed54a7aa2362a916f46503e0627" - integrity sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ== + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz#e8e04b4368d49920abdf1bacc63c67c870635222" + integrity sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.1" + "@fortawesome/fontawesome-common-types" "6.5.2" "@fortawesome/free-solid-svg-icons@^6": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz#737b8d787debe88b400ab7528f47be333031274a" - integrity sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ== + version "6.5.2" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz#9b40b077b27400a5e9fcbf2d15b986c7be69e9ca" + integrity sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.1" + "@fortawesome/fontawesome-common-types" "6.5.2" "@fortawesome/react-fontawesome@^0": version "0.2.0" diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java index 93d65426b61..d877600db13 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java @@ -1,32 +1,31 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.builder.xml.dom; -import com.yahoo.config.provision.ClusterInfo; -import com.yahoo.config.provision.IntRange; import com.yahoo.collections.Pair; import com.yahoo.component.Version; import com.yahoo.config.application.api.DeployLogger; -import com.yahoo.config.provision.ZoneEndpoint; import com.yahoo.config.model.ConfigModelContext; import com.yahoo.config.provision.Capacity; import com.yahoo.config.provision.CloudAccount; +import com.yahoo.config.provision.ClusterInfo; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.DockerImage; +import com.yahoo.config.provision.IntRange; import com.yahoo.config.provision.NodeResources; +import com.yahoo.config.provision.ZoneEndpoint; import com.yahoo.text.XML; import com.yahoo.vespa.model.HostResource; import com.yahoo.vespa.model.HostSystem; import com.yahoo.vespa.model.container.xml.ContainerModelBuilder; import org.w3c.dom.Element; import org.w3c.dom.Node; + import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.Function; import java.util.function.ToDoubleFunction; -import java.util.logging.Level; /** * A common utility class to represent a requirement for nodes during model building. @@ -77,8 +76,10 @@ public class NodesSpecification { Optional<CloudAccount> cloudAccount, boolean hasCountAttribute) { if (max.smallerThan(min)) - throw new IllegalArgumentException("Min resources must be larger or equal to max resources, but " + + throw new IllegalArgumentException("Max resources must be larger or equal to min resources, but " + max + " is smaller than " + min); + if (min.nodes() < 1) + throw new IllegalArgumentException("Min node count cannot be less than 1, but is " + min.nodes()); // Non-scaled resources must be equal if ( ! min.nodeResources().justNonNumbers().equals(max.nodeResources().justNonNumbers())) @@ -128,6 +129,9 @@ public class NodesSpecification { var groups = rangeFrom(nodesElement, "groups"); var groupSize = rangeFrom(nodesElement, "group-size"); + if (nodes.from().orElse(1) < 1) + throw new IllegalArgumentException("Min node resources cannot be less than 1, but is " + nodes.from().getAsInt()); + // Find the tightest possible limits for groups to avoid falsely concluding we are autoscaling // when only specifying group size int defaultMinGroups = nodes.from().orElse(1) / groupSize.to().orElse(nodes.from().orElse(1)); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java index 08b0398a98f..5f824950ecd 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java @@ -24,7 +24,6 @@ public class HostedSslConnectorFactory extends ConnectorFactory { private final SslClientAuth clientAuth; private final List<String> tlsCiphersOverride; private final boolean proxyProtocolEnabled; - private final boolean proxyProtocolMixedMode; private final Duration endpointConnectionTtl; private final List<String> remoteAddressHeaders; private final List<String> remotePortHeaders; @@ -37,7 +36,6 @@ public class HostedSslConnectorFactory extends ConnectorFactory { this.clientAuth = builder.clientAuth; this.tlsCiphersOverride = List.copyOf(builder.tlsCiphersOverride); this.proxyProtocolEnabled = builder.proxyProtocolEnabled; - this.proxyProtocolMixedMode = builder.proxyProtocolMixedMode; this.endpointConnectionTtl = builder.endpointConnectionTtl; this.remoteAddressHeaders = List.copyOf(builder.remoteAddressHeaders); this.remotePortHeaders = List.copyOf(builder.remotePortHeaders); @@ -70,7 +68,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory { } connectorBuilder .proxyProtocol(new ConnectorConfig.ProxyProtocol.Builder() - .enabled(proxyProtocolEnabled).mixedMode(proxyProtocolMixedMode)) + .enabled(proxyProtocolEnabled)) .idleTimeout(Duration.ofSeconds(30).toSeconds()) .maxConnectionLife(endpointConnectionTtl != null ? endpointConnectionTtl.toSeconds() : 0) .accessLog(new ConnectorConfig.AccessLog.Builder() @@ -89,7 +87,6 @@ public class HostedSslConnectorFactory extends ConnectorFactory { SslClientAuth clientAuth; List<String> tlsCiphersOverride = List.of(); boolean proxyProtocolEnabled; - boolean proxyProtocolMixedMode; Duration endpointConnectionTtl; EndpointCertificateSecrets endpointCertificate; String tlsCaCertificatesPem; @@ -101,7 +98,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory { public Builder clientAuth(SslClientAuth auth) { clientAuth = auth; return this; } public Builder endpointConnectionTtl(Duration ttl) { endpointConnectionTtl = ttl; return this; } public Builder tlsCiphersOverride(Collection<String> ciphers) { tlsCiphersOverride = List.copyOf(ciphers); return this; } - public Builder proxyProtocol(boolean enabled, boolean mixedMode) { proxyProtocolEnabled = enabled; proxyProtocolMixedMode = mixedMode; return this; } + public Builder proxyProtocol(boolean enabled) { proxyProtocolEnabled = enabled; return this; } public Builder endpointCertificate(EndpointCertificateSecrets cert) { this.endpointCertificate = cert; return this; } public Builder tlsCaCertificatesPath(String path) { this.tlsCaCertificatesPath = path; return this; } public Builder tlsCaCertificatesPem(String pem) { this.tlsCaCertificatesPem = pem; return this; } 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 c71dbb158b0..eac03531b86 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 @@ -598,7 +598,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { // If the deployment contains certificate/private key reference, setup TLS port var builder = HostedSslConnectorFactory.builder(serverName, getMtlsDataplanePort(state)) - .proxyProtocol(true, state.getProperties().featureFlags().enableProxyProtocolMixedMode()) + .proxyProtocol(state.zone().cloud().useProxyProtocol()) .tlsCiphersOverride(state.getProperties().tlsCiphersOverride()) .endpointConnectionTtl(state.getProperties().endpointConnectionTtl()); var endpointCert = state.endpointCertificateSecrets().orElse(null); @@ -657,7 +657,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { // Setup dedicated connector var connector = HostedSslConnectorFactory.builder(server.getComponentId().getName()+"-token", tokenPort) .tokenEndpoint(true) - .proxyProtocol(false, false) + .proxyProtocol(false) .endpointCertificate(endpointCert) .remoteAddressHeader("X-Forwarded-For") .remotePortHeader("X-Forwarded-Port") diff --git a/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecificationTest.java b/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecificationTest.java index a40d5f22939..344471cada0 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecificationTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecificationTest.java @@ -91,6 +91,8 @@ public class NodesSpecificationTest { () -> nodesSpecification("<nodes><resources memory='b' /></nodes>")); assertThrows(IllegalArgumentException.class, () -> nodesSpecification("<nodes><resources memory='Yb' /></nodes>")); + assertThrows(IllegalArgumentException.class, + () -> nodesSpecification("<nodes count='[0, 1]'></nodes>")); } @Test diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Cloud.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Cloud.java index 38705b02a28..463d9edcdad 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/Cloud.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Cloud.java @@ -57,6 +57,11 @@ public class Cloud { return account; } + /** Returns whether load balancers use proxy protocol v1 or not (e.g. use source NAT). */ + public boolean useProxyProtocol() { + return !name.equals(CloudName.AZURE); + } + /** For testing purposes only */ public static Cloud defaultCloud() { return new Builder().build(); diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Zone.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Zone.java index 5ef42d12dc1..73c6010f514 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/Zone.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Zone.java @@ -54,11 +54,6 @@ public class Zone { this.region = region; } - // TODO(mpolden): For compatibility with older config models. Remove when versions < 8.76 are gone - public Cloud getCloud() { - return cloud(); - } - /** Returns the current cloud */ public Cloud cloud() { return cloud; } @@ -102,5 +97,10 @@ public class Zone { return Objects.hash(environment, region); } + // TODO(mpolden): For compatibility with older config models. Remove when versions < 8.327 are gone + @Deprecated(forRemoval = true) + public Cloud getCloud() { + return cloud(); + } } diff --git a/configdefinitions/src/main/java/com/yahoo/search/significance/config/package-info.java b/configdefinitions/src/main/java/com/yahoo/search/significance/config/package-info.java new file mode 100644 index 00000000000..1093e194c87 --- /dev/null +++ b/configdefinitions/src/main/java/com/yahoo/search/significance/config/package-info.java @@ -0,0 +1,6 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.search.significance.config; + +import com.yahoo.osgi.annotation.ExportPackage; + diff --git a/configdefinitions/src/vespa/CMakeLists.txt b/configdefinitions/src/vespa/CMakeLists.txt index 049475c9c1b..b80a7ac73e3 100644 --- a/configdefinitions/src/vespa/CMakeLists.txt +++ b/configdefinitions/src/vespa/CMakeLists.txt @@ -92,3 +92,5 @@ install_config_definition(col-bert-embedder.def embedding.col-bert-embedder.def) install_config_definition(splade-embedder.def embedding.splade-embedder.def) install_config_definition(cloud-data-plane-filter.def jdisc.http.filter.security.cloud.config.cloud-data-plane-filter.def) install_config_definition(cloud-token-data-plane-filter.def jdisc.http.filter.security.cloud.config.cloud-token-data-plane-filter.def) +install_config_definition(significance.def search.significance.config.significance.def) + diff --git a/configdefinitions/src/vespa/significance.def b/configdefinitions/src/vespa/significance.def new file mode 100644 index 00000000000..e0cc5b4c611 --- /dev/null +++ b/configdefinitions/src/vespa/significance.def @@ -0,0 +1,6 @@ +# Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +namespace=search.significance.config + +model[].language string +model[].path model + diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java index c2f101d7784..ebd5c38e3a3 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/state/StateHandler.java @@ -123,8 +123,10 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe } private String resolveContentType(URI requestUri) { - if (resolvePath(requestUri).equals(HISTOGRAMS_PATH) || isPrometheusRequest(requestUri.getQuery())) { + if (resolvePath(requestUri).equals(HISTOGRAMS_PATH)) { return "text/plain; charset=utf-8"; + } else if (isPrometheusRequest(requestUri.getQuery())) { + return "text/plain; version=0.0.4"; } else { return "application/json"; } @@ -224,45 +226,38 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe var timestamp = snapshot.getToTime(TimeUnit.MILLISECONDS); var builder = new StringBuilder(); builder.append("# NOTE: THIS API IS NOT INTENDED FOR PUBLIC USE\n"); + var metrics = new ArrayList<PrometheusEntry>(); + for (var tuple : collapseMetrics(snapshot, consumer)) { var dims = toPrometheusDimensions(tuple.dim); var metricName = prometheusSanitizedName(tuple.key) + "_"; if (tuple.val instanceof GaugeMetric gauge) { - appendPrometheusEntry(builder, metricName + "max", dims, gauge.getMax(), timestamp); - appendPrometheusEntry(builder, metricName + "sum", dims, gauge.getSum(), timestamp); - appendPrometheusEntry(builder, metricName + "count", dims, gauge.getCount(), timestamp); + metrics.add(new PrometheusEntry(metricName + "max", dims, gauge.getMax())); + metrics.add(new PrometheusEntry(metricName + "sum", dims, gauge.getSum())); + metrics.add(new PrometheusEntry(metricName + "count", dims, gauge.getCount())); if (gauge.getPercentiles().isPresent()) { for (Tuple2<String, Double> prefixAndValue : gauge.getPercentiles().get()) { - appendPrometheusEntry(builder, metricName + prefixAndValue.first + "percentile", dims, prefixAndValue.second, timestamp); + metrics.add(new PrometheusEntry(metricName + prefixAndValue.first + "percentile", dims, prefixAndValue.second)); } } } else if (tuple.val instanceof CountMetric count) { - appendPrometheusEntry(builder, metricName + "count", dims, count.getCount(), timestamp); + metrics.add(new PrometheusEntry(metricName + "count", dims, count.getCount())); } } + Collections.sort(metrics); + metrics.forEach(prometheusEntry -> prometheusEntry.appendPrometheusEntry(builder, timestamp)); return builder.toString().getBytes(UTF_8); } - private void appendPrometheusEntry(StringBuilder builder, String metricName, String dimension, Number value, long timeStamp) { - builder.append("# HELP ") - .append(metricName) - .append("\n# TYPE ") - .append(metricName) - .append(" untyped\n"); - - builder.append(metricName) - .append("{").append(dimension).append("}") - .append(" ").append(sanitizeIfDouble(value)).append(" ") - .append(timeStamp).append("\n"); - } - private String toPrometheusDimensions(MetricDimensions dimensions) { - if (dimensions == null) return ""; + if (dimensions == null || !dimensions.iterator().hasNext()) return ""; StringBuilder builder = new StringBuilder(); + builder.append("{"); dimensions.forEach(entry -> { - var sanitized = prometheusSanitizedName(entry.getKey()) + "=\"" + entry.getValue() + "\","; + var sanitized = prometheusSanitizedName(entry.getKey()) + "=\"" + escapedLabelValue(entry.getValue()) + "\","; builder.append(sanitized); }); + builder.append("}"); return builder.toString(); } @@ -385,8 +380,33 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe return name.replaceAll("\\.", "_"); } - private Number sanitizeIfDouble(Number num) { - return num instanceof Double d ? sanitizeDouble(d) : num; + private String sanitizeIfDouble(Number num) { + return num instanceof Double d ? prettyDouble(d) : num.toString(); + } + + private String escapedLabelValue(String labelValue) { + var builder = new StringBuilder(); + for (int i = 0; i < labelValue.length(); i++) { + var c = labelValue.charAt(i); + switch (c) { + case '\n': + builder.append("\\n"); + break; + case '\\': + case '"': + builder.append("\\") + .append(c); + break; + default: + builder.append(c); + } + } + return builder.toString(); + } + + private String prettyDouble(Double d) { + if (Double.isFinite(d) || d.isNaN()) return d.toString(); + return d.equals(Double.NEGATIVE_INFINITY) ? "-Inf" : "Inf"; } private static byte[] toPrettyString(JsonNode resources) throws JsonProcessingException { @@ -419,4 +439,29 @@ public class StateHandler extends AbstractRequestHandler implements CapabilityRe } } + class PrometheusEntry implements Comparable<PrometheusEntry> { + final String metricName; + final String dimensions; + final Number value; + + public PrometheusEntry(String metricName, String dimensions, Number value) { + this.metricName = metricName; + this.dimensions = dimensions; + this.value = value; + } + + @Override + public int compareTo(PrometheusEntry o) { + int comparison = this.metricName.compareTo(o.metricName); + return comparison != 0 ? comparison : this.dimensions.compareTo(o.dimensions); + } + + public void appendPrometheusEntry(StringBuilder builder, long timestamp) { + builder.append(metricName) + .append(dimensions) + .append(" ").append(sanitizeIfDouble(value)).append(" ") + .append(timestamp).append("\n"); + } + } + } diff --git a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def index 95b93617b6f..2906f75a1f5 100644 --- a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def +++ b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def @@ -123,6 +123,8 @@ healthCheckProxy.cacheExpiry double default=1.0 proxyProtocol.enabled bool default=false # Allow https in parallel with proxy protocol +# TODO Vespa 9 Remove +# Unused since 8.327 proxyProtocol.mixedMode bool default=false # Maximum number of request per connection before server marks connections as non-persistent. Set to '0' to disable. diff --git a/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java b/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java index 3d1a4a3583e..c99a61781cb 100644 --- a/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java +++ b/container-core/src/test/java/com/yahoo/container/jdisc/state/StateHandlerTest.java @@ -80,28 +80,34 @@ public class StateHandlerTest extends StateHandlerTestBase { @Test public void testPrometheusFormat() { var counterContext = StateMetricContext.newInstance(Map.of("label1", "val1", "label2", "val2")); + var otherContext = StateMetricContext.newInstance(Map.of( + "label1", "This label has \"quotes\"", + "label2", "This label, a\nnewline")); var snapshot = new MetricSnapshot(0L, SNAPSHOT_INTERVAL, TimeUnit.MILLISECONDS); - snapshot.set(null, "bar", 20); - snapshot.set(null, "bar", 40); snapshot.add(counterContext, "some.counter", 10); snapshot.add(counterContext, "some.counter", 20); + snapshot.add(otherContext, "some.counter", 1); + snapshot.add(otherContext, "some.counter", 2); + snapshot.set(null, "bar", 20); + snapshot.set(null, "bar", 40); + snapshot.set(null, "testing.infinity", Double.NEGATIVE_INFINITY); + snapshot.set(null, "testing.nan", Double.NaN); snapshotProvider.setSnapshot(snapshot); var response = requestAsString(V1_URI + "metrics?format=prometheus"); var expectedResponse = """ # NOTE: THIS API IS NOT INTENDED FOR PUBLIC USE - # HELP bar_max - # TYPE bar_max untyped - bar_max{} 40.0 300000 - # HELP bar_sum - # TYPE bar_sum untyped - bar_sum{} 60.0 300000 - # HELP bar_count - # TYPE bar_count untyped - bar_count{} 2 300000 - # HELP some_counter_count - # TYPE some_counter_count untyped + bar_count 2 300000 + bar_max 40.0 300000 + bar_sum 60.0 300000 + some_counter_count{label1="This label has \\"quotes\\"",label2="This label, a\\nnewline",} 3 300000 some_counter_count{label1="val1",label2="val2",} 30 300000 + testing_infinity_count 1 300000 + testing_infinity_max -Inf 300000 + testing_infinity_sum -Inf 300000 + testing_nan_count 1 300000 + testing_nan_max NaN 300000 + testing_nan_sum NaN 300000 """; assertEquals(expectedResponse, response); } diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/DataplaneProxyService.java b/container-disc/src/main/java/com/yahoo/container/jdisc/DataplaneProxyService.java index d94244b0e47..e1a753ddf27 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/DataplaneProxyService.java +++ b/container-disc/src/main/java/com/yahoo/container/jdisc/DataplaneProxyService.java @@ -134,7 +134,7 @@ public class DataplaneProxyService extends AbstractComponent { } else { if (state == NginxState.RELOAD_REQUIRED) { try { - proxyCommands.reload(); + proxyCommands.reload(nginxConf); changeState(convergeTo); } catch (Exception e) { logger.log(Level.INFO, "Failed to reconfigure nginx, will retry."); @@ -148,7 +148,7 @@ public class DataplaneProxyService extends AbstractComponent { } else if (convergeTo == NginxState.STOPPED) { if (proxyCommands.isRunning()) { try { - proxyCommands.stop(); + proxyCommands.stop(nginxConf); } catch (Exception e) { logger.log(Level.INFO, "Failed to stop nginx, will retry"); logger.log(Level.FINE, "Exception from nginx stop", e); @@ -240,8 +240,8 @@ public class DataplaneProxyService extends AbstractComponent { public interface ProxyCommands { void start(Path configFile); - void stop(); - void reload(); + void stop(Path configFile); + void reload(Path configFile); boolean isRunning(); } @@ -264,11 +264,12 @@ public class DataplaneProxyService extends AbstractComponent { } @Override - public void stop() { + public void stop(Path configFile) { try { Process stopCommand = new ProcessBuilder().command( "nginx", - "-s", "stop" + "-s", "stop", + "-c", configFile.toString() ).start(); int exitCode = stopCommand.waitFor(); if (exitCode != 0) { @@ -281,11 +282,12 @@ public class DataplaneProxyService extends AbstractComponent { } @Override - public void reload() { + public void reload(Path configFile) { try { Process reloadCommand = new ProcessBuilder().command( "nginx", - "-s", "reload" + "-s", "reload", + "-c", configFile.toString() ).start(); int exitCode = reloadCommand.waitFor(); if (exitCode != 0) { diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/DataplaneProxyServiceTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/DataplaneProxyServiceTest.java index 719a6c0af85..47ff646918d 100644 --- a/container-disc/src/test/java/com/yahoo/container/jdisc/DataplaneProxyServiceTest.java +++ b/container-disc/src/test/java/com/yahoo/container/jdisc/DataplaneProxyServiceTest.java @@ -67,7 +67,7 @@ public class DataplaneProxyServiceTest { @Test public void retries_reload_errors() throws IOException { - Mockito.doThrow(new RuntimeException("IO error")).doNothing().when(proxyCommandsMock).reload(); + Mockito.doThrow(new RuntimeException("IO error")).doNothing().when(proxyCommandsMock).reload(any()); when(proxyCommandsMock.isRunning()).thenReturn(false); DataplaneProxyService service = dataplaneProxyService(proxyCommandsMock); @@ -83,7 +83,7 @@ public class DataplaneProxyServiceTest { assertEquals(DataplaneProxyService.NginxState.RELOAD_REQUIRED, service.state()); service.converge(); assertEquals(DataplaneProxyService.NginxState.RUNNING, service.state()); - verify(proxyCommandsMock, times(2)).reload(); + verify(proxyCommandsMock, times(2)).reload(any()); } @Test @@ -98,7 +98,7 @@ public class DataplaneProxyServiceTest { assertTrue(proxyCommands.isRunning()); // Simulate nginx process dying - proxyCommands.stop(); + proxyCommands.stop(null); assertFalse(proxyCommands.isRunning()); service.converge(); assertTrue(proxyCommands.isRunning()); @@ -136,7 +136,7 @@ public class DataplaneProxyServiceTest { reset(proxyCommandsMock); when(mockProxyCommands.isRunning()).thenReturn(true).thenReturn(false); - doThrow(new RuntimeException("Failed to stop proxy")).when(proxyCommandsMock).stop(); + doThrow(new RuntimeException("Failed to stop proxy")).when(proxyCommandsMock).stop(any()); Thread thread = new Thread(service::deconstruct);// deconstruct will block until nginx is stopped thread.start(); @@ -151,7 +151,7 @@ public class DataplaneProxyServiceTest { assertEquals(service.state(), DataplaneProxyService.NginxState.STOPPED); thread.join(); - verify(mockProxyCommands, times(1)).stop(); + verify(mockProxyCommands, times(1)).stop(any()); } private DataplaneProxyService dataplaneProxyService(DataplaneProxyService.ProxyCommands proxyCommands) throws IOException { @@ -190,12 +190,12 @@ public class DataplaneProxyServiceTest { } @Override - public void stop() { + public void stop(Path configFile) { running = false; } @Override - public void reload() { + public void reload(Path configFile) { } diff --git a/container-llama/CMakeLists.txt b/container-llama/CMakeLists.txt new file mode 100644 index 00000000000..ba41a4ef835 --- /dev/null +++ b/container-llama/CMakeLists.txt @@ -0,0 +1,2 @@ +# Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +install_jar(container-llama.jar) diff --git a/container-llama/README.md b/container-llama/README.md new file mode 100644 index 00000000000..3f172726124 --- /dev/null +++ b/container-llama/README.md @@ -0,0 +1,4 @@ +<!-- Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +# container-llama + +llama repackaged as a bundle diff --git a/container-llama/pom.xml b/container-llama/pom.xml new file mode 100644 index 00000000000..1eb057abcaf --- /dev/null +++ b/container-llama/pom.xml @@ -0,0 +1,97 @@ +<?xml version="1.0"?> +<!-- Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>container-llama</artifactId> + <packaging>container-plugin</packaging> + <version>8-SNAPSHOT</version> + <parent> + <groupId>com.yahoo.vespa</groupId> + <artifactId>parent</artifactId> + <version>8-SNAPSHOT</version> + <relativePath>../parent/pom.xml</relativePath> + </parent> + <properties> + <maven.javadoc.skip>true</maven.javadoc.skip> <!-- Javadoc plugin fails because of no source code in module --> + </properties> + <dependencies> + <!-- provided --> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>annotations</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <!-- Not directly used in this module, but needed to get Import-Packages for JDK packages it exports. --> + <groupId>com.yahoo.vespa</groupId> + <artifactId>jdisc_core</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <!-- compile --> + <dependency> + <groupId>de.kherud</groupId> + <artifactId>llama</artifactId> + <scope>compile</scope> + <exclusions> + <exclusion> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>com.yahoo.vespa</groupId> + <artifactId>bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <bundleType>CORE</bundleType> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <minimizeJar>false</minimizeJar> + <createDependencyReducedPom>false</createDependencyReducedPom> + <filters> + <filter> + <artifact>de.kherud:*</artifact> + <excludes> + <exclude>de/kherud/llama/Linux-Android//**</exclude> + <exclude>de/kherud/llama/Linux/**</exclude> + <exclude>de/kherud/llama/Mac/**</exclude> + <exclude>de/kherud/llama/Windows/**</exclude> + </excludes> + </filter> + </filters> + <transformers> + <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <manifestEntries> + <Bundle-Activator>ai.vespa.llama.LlamaBundleActivator</Bundle-Activator> + </manifestEntries> + </transformer> + </transformers> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/container-llama/src/main/java/ai/vespa/llama/LlamaBundleActivator.java b/container-llama/src/main/java/ai/vespa/llama/LlamaBundleActivator.java new file mode 100644 index 00000000000..11ba05e363d --- /dev/null +++ b/container-llama/src/main/java/ai/vespa/llama/LlamaBundleActivator.java @@ -0,0 +1,51 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +package ai.vespa.llama; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import java.util.logging.Logger; + +/** + * @author arnej + * Finds native libraries when the bundle is activated. + **/ +public class LlamaBundleActivator implements BundleActivator { + + private static final String PATH_PROPNAME = "de.kherud.llama.lib.path"; + private static final Logger log = Logger.getLogger(LlamaBundleActivator.class.getName()); + + @Override + public void start(BundleContext ctx) { + log.fine("start bundle"); + if (checkFilenames( + "/dev/nvidia0", + "/opt/vespa-deps/lib64/cuda/libllama.so", + "/opt/vespa-deps/lib64/cuda/libjllama.so")) { + System.setProperty(PATH_PROPNAME, "/opt/vespa-deps/lib64/cuda"); + } else if (checkFilenames( + "/opt/vespa-deps/lib64/libllama.so", + "/opt/vespa-deps/lib64/libjllama.so")) { + System.setProperty(PATH_PROPNAME, "/opt/vespa-deps/lib64"); + } else { + throw new IllegalArgumentException("Cannot find shared libraries"); + } + } + + @Override + public void stop(BundleContext ctx) { + log.fine("stop bundle"); + } + + private boolean checkFilenames(String... filenames) { + for (String fn : filenames) { + var f = new java.io.File(fn); + if (! f.canRead()) { + return false; + } + } + return true; + } + +} diff --git a/dependency-versions/pom.xml b/dependency-versions/pom.xml index dc375ec647f..da857b25475 100644 --- a/dependency-versions/pom.xml +++ b/dependency-versions/pom.xml @@ -66,8 +66,8 @@ <assertj.vespa.version>3.25.3</assertj.vespa.version> <!-- Athenz dependencies. Make sure these dependencies match those in Vespa's internal repositories --> - <aws-sdk.vespa.version>1.12.692</aws-sdk.vespa.version> - <athenz.vespa.version>1.11.54</athenz.vespa.version> + <aws-sdk.vespa.version>1.12.693</aws-sdk.vespa.version> + <athenz.vespa.version>1.11.55</athenz.vespa.version> <!-- Athenz END --> <!-- WARNING: If you change curator version, you also need to update @@ -115,9 +115,10 @@ <junit.vespa.version>5.10.2</junit.vespa.version> <junit.platform.vespa.version>1.10.2</junit.platform.vespa.version> <junit4.vespa.version>4.13.2</junit4.vespa.version> + <kherud.llama.vespa.version>2.3.5</kherud.llama.vespa.version> <luben.zstd.vespa.version>1.5.6-1</luben.zstd.vespa.version> <lucene.vespa.version>9.10.0</lucene.vespa.version> - <maven-archiver.vespa.version>3.6.1</maven-archiver.vespa.version> + <maven-archiver.vespa.version>3.6.2</maven-archiver.vespa.version> <maven-wagon.vespa.version>3.5.3</maven-wagon.vespa.version> <mimepull.vespa.version>1.10.0</mimepull.vespa.version> <mockito.vespa.version>5.11.0</mockito.vespa.version> @@ -130,7 +131,9 @@ <org.json.vespa.version>20240303</org.json.vespa.version> <org.lz4.vespa.version>1.8.0</org.lz4.vespa.version> <prometheus.client.vespa.version>0.16.0</prometheus.client.vespa.version> + <plexus-archiver.vespa.version>4.9.2</plexus-archiver.vespa.version> <plexus-interpolation.vespa.version>1.27</plexus-interpolation.vespa.version> + <plexus-io.vespa.version>3.4.2</plexus-io.vespa.version> <plexus-utils.vespa.version>3.5.1</plexus-utils.vespa.version> <plexus-xml.vespa.version>3.0.0</plexus-xml.vespa.version> <protobuf.vespa.version>3.25.3</protobuf.vespa.version> diff --git a/dist/vespa.spec b/dist/vespa.spec index 53e82e372af..4886bd43db8 100644 --- a/dist/vespa.spec +++ b/dist/vespa.spec @@ -629,6 +629,7 @@ fi %{_prefix}/lib/jars/config-provisioning-jar-with-dependencies.jar %{_prefix}/lib/jars/container-apache-http-client-bundle-jar-with-dependencies.jar %{_prefix}/lib/jars/container-disc-jar-with-dependencies.jar +%{_prefix}/lib/jars/container-llama.jar %{_prefix}/lib/jars/container-onnxruntime.jar %{_prefix}/lib/jars/container-search-and-docproc-jar-with-dependencies.jar %{_prefix}/lib/jars/container-spifly.jar diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ExpressionOptimizer.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ExpressionOptimizer.java index bad8b94d074..a66c47caa85 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ExpressionOptimizer.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ExpressionOptimizer.java @@ -1,7 +1,22 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.indexinglanguage; -import com.yahoo.vespa.indexinglanguage.expressions.*; + +import com.yahoo.vespa.indexinglanguage.expressions.CompositeExpression; +import com.yahoo.vespa.indexinglanguage.expressions.ConstantExpression; +import com.yahoo.vespa.indexinglanguage.expressions.EchoExpression; +import com.yahoo.vespa.indexinglanguage.expressions.Expression; +import com.yahoo.vespa.indexinglanguage.expressions.ForEachExpression; +import com.yahoo.vespa.indexinglanguage.expressions.GetVarExpression; +import com.yahoo.vespa.indexinglanguage.expressions.HostNameExpression; +import com.yahoo.vespa.indexinglanguage.expressions.InputExpression; +import com.yahoo.vespa.indexinglanguage.expressions.NowExpression; +import com.yahoo.vespa.indexinglanguage.expressions.OutputExpression; +import com.yahoo.vespa.indexinglanguage.expressions.RandomExpression; +import com.yahoo.vespa.indexinglanguage.expressions.ScriptExpression; +import com.yahoo.vespa.indexinglanguage.expressions.SetVarExpression; +import com.yahoo.vespa.indexinglanguage.expressions.StatementExpression; +import com.yahoo.vespa.indexinglanguage.expressions.SwitchExpression; import java.util.ArrayList; import java.util.List; @@ -59,7 +74,7 @@ public class ExpressionOptimizer extends ExpressionConverter { } static boolean ignoresInput(Expression exp) { - if (exp instanceof SwitchExpression || exp instanceof ScriptExpression || exp instanceof ForEachExpression ) { + if (exp instanceof SwitchExpression || exp instanceof ScriptExpression || exp instanceof ForEachExpression) { return false; // Switch and script never ignores input. } if (exp instanceof CompositeExpression) { diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java new file mode 100644 index 00000000000..068aa1421f7 --- /dev/null +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java @@ -0,0 +1,43 @@ +package com.yahoo.vespa.indexinglanguage.expressions; + +import com.yahoo.document.DataType; +import com.yahoo.document.datatypes.FieldValue; +import com.yahoo.document.datatypes.NumericFieldValue; + +/** + * Utility expression that will sleep the amount of time given in the numeric field. + * Non-numeric fields will be ignored + * @author baldersheim + */ +public final class BusyWaitExpression extends Expression { + public BusyWaitExpression() { + super(UnresolvedDataType.INSTANCE); + } + + private static double nihlakanta(int i) { + long a = 2 + i * 4L; + return (24 * (a+2))/(double)(a*(a+1)*(a+2)*(a+3)); + } + + @Override + protected void doExecute(ExecutionContext context) { + FieldValue value = context.getValue(); + if (value instanceof NumericFieldValue num) { + double napSecs = num.getNumber().doubleValue(); + long doom = System.nanoTime() + (long)(1_000_000_000.0 * napSecs); + while (doom > System.nanoTime()) { + double pi = 3; + for (int i = 0; i < 1000; i++) { + pi += nihlakanta(i); + } + context.getCache().put("Busy wait computing pi and store it to avoid jit optiming it away", pi); + } + } + } + + @Override protected void doVerify(VerificationContext context) { } + @Override public DataType createdOutputType() { return null; } + @Override public String toString() { return "sleep"; } + @Override public boolean equals(Object obj) { return obj instanceof BusyWaitExpression; } + @Override public int hashCode() { return getClass().hashCode(); } +} diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java index 690e7415801..4001e2a6fd0 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java @@ -27,7 +27,7 @@ public final class EchoExpression extends Expression { @Override protected void doExecute(ExecutionContext context) { - out.println(String.valueOf(context.getValue())); + out.println(context.getValue()); } @Override @@ -47,14 +47,9 @@ public final class EchoExpression extends Expression { @Override public boolean equals(Object obj) { - if (!(obj instanceof EchoExpression)) { - return false; - } - EchoExpression rhs = (EchoExpression)obj; - if (out != rhs.out) { - return false; - } - return true; + if (!(obj instanceof EchoExpression rhs)) return false; + + return out == rhs.out; } @Override diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java new file mode 100644 index 00000000000..f7216fc1c97 --- /dev/null +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java @@ -0,0 +1,36 @@ +package com.yahoo.vespa.indexinglanguage.expressions; + +import com.yahoo.document.DataType; +import com.yahoo.document.datatypes.FieldValue; +import com.yahoo.document.datatypes.NumericFieldValue; + +/** + * Utility expression that will sleep the amount of time given in the numeric field. + * Non-numeric fields will be ignored + * @author baldersheim + */ +public final class SleepExpression extends Expression { + public SleepExpression() { + super(UnresolvedDataType.INSTANCE); + } + + @Override + protected void doExecute(ExecutionContext context) { + FieldValue value = context.getValue(); + if (value instanceof NumericFieldValue num) { + double napSecs = num.getNumber().doubleValue(); + long nanos = (long)(napSecs*1_000_000_000.0); + try { + Thread.sleep(nanos / 1_000_000, (int) (nanos % 1_000_000)); + } catch (InterruptedException e) { + // Do nothing + } + } + } + + @Override protected void doVerify(VerificationContext context) { } + @Override public DataType createdOutputType() { return null; } + @Override public String toString() { return "sleep"; } + @Override public boolean equals(Object obj) { return obj instanceof SleepExpression; } + @Override public int hashCode() { return getClass().hashCode(); } +} diff --git a/indexinglanguage/src/main/javacc/IndexingParser.jj b/indexinglanguage/src/main/javacc/IndexingParser.jj index a3b4039408a..469d96ead60 100644 --- a/indexinglanguage/src/main/javacc/IndexingParser.jj +++ b/indexinglanguage/src/main/javacc/IndexingParser.jj @@ -149,6 +149,7 @@ TOKEN : <ATTRIBUTE: "attribute"> | <BASE64_DECODE: "base64decode"> | <BASE64_ENCODE: "base64encode"> | + <BUSY_WAIT: "busy_wait"> | <CASE: "case"> | <CASE_DEFAULT: "default"> | <CLEAR_STATE: "clear_state"> | @@ -183,6 +184,7 @@ TOKEN : <SELECT_INPUT: "select_input"> | <SET_LANGUAGE: "set_language"> | <SET_VAR: "set_var"> | + <SLEEP: "sleep"> | <SPLIT: "split"> | <STEM: "stem"> | <SUBSTRING: "substring"> | @@ -296,6 +298,7 @@ Expression value() : ( val = attributeExp() | val = base64DecodeExp() | val = base64EncodeExp() | + val = busy_waitExp() | val = clearStateExp() | val = echoExp() | val = embedExp() | @@ -325,6 +328,7 @@ Expression value() : val = setLanguageExp() | val = setValueExp() | val = setVarExp() | + val = sleepExp() | val = splitExp() | val = substringExp() | val = summaryExp() | @@ -371,6 +375,12 @@ Expression base64EncodeExp() : { } { return new Base64EncodeExpression(); } } +Expression busy_waitExp() : { } +{ + ( <BUSY_WAIT> ) + { return new BusyWaitExpression(); } +} + Expression clearStateExp() : { } { ( <CLEAR_STATE> ) @@ -608,6 +618,12 @@ Expression setVarExp() : { return new SetVarExpression(val); } } +Expression sleepExp() : { } +{ + ( <SLEEP> ) + { return new SleepExpression(); } +} + Expression splitExp() : { String val; @@ -783,6 +799,7 @@ String identifier() : ( <ATTRIBUTE> | <BASE64_DECODE> | <BASE64_ENCODE> | + <BUSY_WAIT> | <CASE> | <CASE_DEFAULT> | <CLEAR_STATE> | @@ -817,6 +834,7 @@ String identifier() : <SELECT_INPUT> | <SET_LANGUAGE> | <SET_VAR> | + <SLEEP> | <SPLIT> | <STEM> | <SUBSTRING> | diff --git a/maven-plugins/allowed-maven-dependencies.txt b/maven-plugins/allowed-maven-dependencies.txt index e3414b48ee6..bef72f582e4 100644 --- a/maven-plugins/allowed-maven-dependencies.txt +++ b/maven-plugins/allowed-maven-dependencies.txt @@ -45,12 +45,12 @@ org.apache.maven:maven-resolver-provider:${maven-core.vespa.version} org.apache.maven:maven-settings-builder:${maven-core.vespa.version} org.apache.maven:maven-settings:${maven-core.vespa.version} org.apiguardian:apiguardian-api:${apiguardian.vespa.version} -org.codehaus.plexus:plexus-archiver:4.8.0 +org.codehaus.plexus:plexus-archiver:${plexus-archiver.vespa.version} org.codehaus.plexus:plexus-cipher:2.0 org.codehaus.plexus:plexus-classworlds:2.7.0 org.codehaus.plexus:plexus-component-annotations:2.1.0 org.codehaus.plexus:plexus-interpolation:${plexus-interpolation.vespa.version} -org.codehaus.plexus:plexus-io:${maven-enforcer-plugin.vespa.version} +org.codehaus.plexus:plexus-io:${plexus-io.vespa.version} org.codehaus.plexus:plexus-sec-dispatcher:2.0 org.codehaus.plexus:plexus-utils:${plexus-utils.vespa.version} org.codehaus.plexus:plexus-xml:${plexus-xml.vespa.version} diff --git a/parent/pom.xml b/parent/pom.xml index ca399019aa6..b21e9b844f5 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -594,6 +594,11 @@ <version>${onnxruntime.vespa.version}</version> </dependency> <dependency> + <groupId>de.kherud</groupId> + <artifactId>llama</artifactId> + <version>${kherud.llama.vespa.version}</version> + </dependency> + <dependency> <groupId>com.yahoo.athenz</groupId> <artifactId>athenz-cert-refresher</artifactId> <version>${athenz.vespa.version}</version> @@ -998,11 +1003,21 @@ </dependency> <dependency> <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-archiver</artifactId> + <version>${plexus-archiver.vespa.version}</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-interpolation</artifactId> <version>${plexus-interpolation.vespa.version}</version> </dependency> <dependency> <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-io</artifactId> + <version>${plexus-io.vespa.version}</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-utils</artifactId> <version>${plexus-utils.vespa.version}</version> </dependency> @@ -56,6 +56,7 @@ <module>container-dev</module> <module>container-disc</module> <module>container-documentapi</module> + <module>container-llama</module> <module>container-messagebus</module> <module>container-onnxruntime</module> <module>container-search-and-docproc</module> diff --git a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp index d556d997206..bb79ad85cc0 100644 --- a/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp +++ b/searchlib/src/tests/queryeval/blueprint/blueprint_test.cpp @@ -658,6 +658,7 @@ getExpectedBlueprint() " strict_cost: 0\n" " sourceId: 4294967295\n" " docid_limit: 0\n" + " strict: false\n" " children: std::vector {\n" " [0]: (anonymous namespace)::MyTerm {\n" " isTermLike: true\n" @@ -680,6 +681,7 @@ getExpectedBlueprint() " strict_cost: 0\n" " sourceId: 4294967295\n" " docid_limit: 0\n" + " strict: false\n" " }\n" " }\n" "}\n"; @@ -712,6 +714,7 @@ getExpectedSlimeBlueprint() { " strict_cost: 0.0," " sourceId: 4294967295," " docid_limit: 0," + " strict: false," " children: {" " '[type]': 'std::vector'," " '[0]': {" @@ -738,7 +741,8 @@ getExpectedSlimeBlueprint() { " cost: 0.0," " strict_cost: 0.0," " sourceId: 4294967295," - " docid_limit: 0" + " docid_limit: 0," + " strict: false" " }" " }" "}"; diff --git a/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp b/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp index d3b6a90e5db..72dd2b5a4ad 100644 --- a/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp +++ b/searchlib/src/tests/queryeval/blueprint/intermediate_blueprints_test.cpp @@ -555,6 +555,13 @@ void compare(const Blueprint &bp1, const Blueprint &bp2, bool expect_eq) { check_value(a.asDouble()); check_value(b.asDouble()); return true; + } else if (field == "strict") { + // ignore strict-tagging differences between optimized and unoptimized blueprint trees + if (a.type().getId() == vespalib::slime::BOOL::ID && + b.type().getId() == vespalib::slime::BOOL::ID) + { + return true; + } } } if (expect_eq) { diff --git a/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp b/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp index 992ac320385..2bd560637d2 100644 --- a/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp +++ b/searchlib/src/tests/queryeval/parallel_weak_and/parallel_weak_and_test.cpp @@ -635,6 +635,7 @@ TEST(ParallelWeakAndTest, require_that_asString_on_blueprint_works) " strict_cost: 0\n" " sourceId: 4294967295\n" " docid_limit: 0\n" + " strict: false\n" " _weights: std::vector {\n" " [0]: 5\n" " }\n" @@ -660,6 +661,7 @@ TEST(ParallelWeakAndTest, require_that_asString_on_blueprint_works) " strict_cost: 0\n" " sourceId: 4294967295\n" " docid_limit: 0\n" + " strict: false\n" " }\n" " }\n" "}\n"; diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp index 8ffc43928e1..6d79f7bcb26 100644 --- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp @@ -305,7 +305,7 @@ public: }; double est = OrFlow::estimate_of(MyAdapter(docid_limit), _estimates); return {est, OrFlow::cost_of(MyAdapter(docid_limit), _estimates, false), - OrFlow::cost_of(MyAdapter(docid_limit), _estimates, true) + queryeval::flow::array_cost(est, _estimates.size())}; + OrFlow::cost_of(MyAdapter(docid_limit), _estimates, true) + queryeval::flow::heap_cost(est, _estimates.size())}; } SearchIterator::UP diff --git a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp index 1d323bf298f..73f99d28eda 100644 --- a/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/blueprint.cpp @@ -398,7 +398,7 @@ Blueprint::visitMembers(vespalib::ObjectVisitor &visitor) const visitor.visitFloat("strict_cost", strict_cost()); visitor.visitInt("sourceId", _sourceId); visitor.visitInt("docid_limit", _docid_limit); - // visitor.visitBool("strict", _strict); + visitor.visitBool("strict", _strict); } namespace blueprint { diff --git a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp index 61ae7b51de1..8b5e76085d2 100644 --- a/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp +++ b/searchlib/src/vespa/searchlib/queryeval/equiv_blueprint.cpp @@ -72,7 +72,7 @@ EquivBlueprint::calculate_flow_stats(uint32_t docid_limit) const } double est = OrFlow::estimate_of(_terms); return {est, OrFlow::cost_of(_terms, false), - OrFlow::cost_of(_terms, true) + flow::array_cost(est, _terms.size())}; + OrFlow::cost_of(_terms, true) + flow::heap_cost(est, _terms.size())}; } SearchIterator::UP diff --git a/searchlib/src/vespa/searchlib/queryeval/flow_tuning.h b/searchlib/src/vespa/searchlib/queryeval/flow_tuning.h index 53f2be88c1f..51e544b2e30 100644 --- a/searchlib/src/vespa/searchlib/queryeval/flow_tuning.h +++ b/searchlib/src/vespa/searchlib/queryeval/flow_tuning.h @@ -10,10 +10,6 @@ inline double heap_cost(double my_est, size_t num_children) { return my_est * std::log2(std::max(size_t(1),num_children)); } -inline double array_cost(double my_est, size_t num_children) { - return my_est * num_children; -} - /** * The following constants and formulas were derived after analyzing term search over attributes * (with and without fast-search) and disk index by using the iterator benchmark program: diff --git a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt index 9ffde513481..fd7baf675b6 100644 --- a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt +++ b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt @@ -30,6 +30,7 @@ com.google.jimfs:jimfs:${jimfs.vespa.version} com.google.protobuf:protobuf-java:${protobuf.vespa.version} com.ibm.icu:icu4j:${icu4j.vespa.version} com.microsoft.onnxruntime:onnxruntime:${onnxruntime.vespa.version} +de.kherud:llama:${kherud.llama.vespa.version} com.sun.activation:javax.activation:1.2.0 com.sun.istack:istack-commons-runtime:4.1.2 com.sun.xml.bind:jaxb-core:${jaxb-core.vespa.version} @@ -131,12 +132,12 @@ org.assertj:assertj-core:${assertj.vespa.version} org.bouncycastle:bcpkix-jdk18on:${bouncycastle.vespa.version} org.bouncycastle:bcprov-jdk18on:${bouncycastle.vespa.version} org.bouncycastle:bcutil-jdk18on:${bouncycastle.vespa.version} -org.codehaus.plexus:plexus-archiver:4.8.0 +org.codehaus.plexus:plexus-archiver:${plexus-archiver.vespa.version} org.codehaus.plexus:plexus-classworlds:2.7.0 org.codehaus.plexus:plexus-component-annotations:2.1.0 org.codehaus.plexus:plexus-container-default:1.0-alpha-9-stable-1 org.codehaus.plexus:plexus-interpolation:${plexus-interpolation.vespa.version} -org.codehaus.plexus:plexus-io:${maven-enforcer-plugin.vespa.version} +org.codehaus.plexus:plexus-io:${plexus-io.vespa.version} org.codehaus.plexus:plexus-utils:${plexus-utils.vespa.version} org.eclipse.angus:angus-activation:${eclipse-angus.vespa.version} org.eclipse.collections:eclipse-collections-api:${eclipse-collections.vespa.version} diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/GracePeriodCircuitBreaker.java b/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/GracePeriodCircuitBreaker.java index 73bdb65eefb..1ea2089c0eb 100644 --- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/GracePeriodCircuitBreaker.java +++ b/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/GracePeriodCircuitBreaker.java @@ -66,7 +66,7 @@ public class GracePeriodCircuitBreaker implements FeedClient.CircuitBreaker { public void success() { failingSinceMillis.set(NEVER); if ( ! open.get() && halfOpen.compareAndSet(true, false)) - log.log(FINE, "Circuit breaker is now closed"); + log.log(INFO, "Circuit breaker is now closed, after a request was successful"); } @Override diff --git a/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/StaticThrottler.java b/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/StaticThrottler.java index e26f4b83a1e..cc4e5edd135 100644 --- a/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/StaticThrottler.java +++ b/vespa-feed-client/src/main/java/ai/vespa/feed/client/impl/StaticThrottler.java @@ -21,7 +21,7 @@ public class StaticThrottler implements Throttler { private final AtomicLong targetX10; public StaticThrottler(FeedClientBuilderImpl builder) { - minInflight = 16L * builder.connectionsPerEndpoint * builder.endpoints.size(); + minInflight = 8L * builder.connectionsPerEndpoint * builder.endpoints.size(); maxInflight = 256 * minInflight; // 4096 max streams per connection on the server side. targetX10 = new AtomicLong(10 * maxInflight); // 10x the actual value to allow for smaller updates. } |