aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java6
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java10
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java10
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/StorageNode.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java17
-rwxr-xr-xconfig-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java20
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java12
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java7
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java49
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java19
-rw-r--r--configserver/src/main/resources/configserver-app/services.xml1
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java23
-rw-r--r--container-core/abi-spec.json4
-rw-r--r--container-core/src/main/resources/configdefinitions/threadpool.def5
-rw-r--r--eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp85
-rw-r--r--eval/src/vespa/eval/eval/tensor_function.cpp20
-rw-r--r--eval/src/vespa/eval/eval/tensor_function.h34
-rw-r--r--eval/src/vespa/eval/tensor/default_tensor_engine.cpp2
-rw-r--r--eval/src/vespa/eval/tensor/dense/CMakeLists.txt1
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp189
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_lambda_function.h30
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java7
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/DiskSize.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java46
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java13
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java11
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java30
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java45
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java48
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java45
-rw-r--r--searchcore/src/vespa/searchcore/grouping/groupingcontext.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/grouping/groupingsession.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/docsummary/fieldcache.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/docsummary/fieldcacherepo.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp5
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastorecontext.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h2
-rw-r--r--searchcore/src/vespa/searchcore/proton/metrics/documentdb_job_trackers.cpp18
-rw-r--r--searchcore/src/vespa/searchcore/proton/metrics/job_tracked_flush_target.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/metrics/trans_log_server_metrics.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp5
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/attribute_writer_factory.h2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/bootstrapconfigmanager.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/clusterstatehandler.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/diskindex/disktermblueprint.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/filter_wrapper.h8
-rw-r--r--vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java5
-rw-r--r--vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/FeedHandlerV3.java21
-rw-r--r--vespaclient-container-plugin/src/test/java/com/yahoo/feedhandler/v3/FeedTesterV3.java14
-rw-r--r--zookeeper-server/zookeeper-server-3.5.8/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java2
-rw-r--r--zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java45
61 files changed, 595 insertions, 385 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
index 2911eae8d83..e465f97ae4c 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
@@ -79,10 +79,10 @@ public interface ModelContext {
// TODO Revisit in May or June 2020
double queueSizeFactor();
- // TODO Revisit in May or June 2020
- double defaultSoftStartSeconds();
+ // TODO Remove when 7.229 is last
+ default double defaultSoftStartSeconds() { return 0; }
- // TODO Remove when 7.225 is last
+ // TODO Remove when 7.226 is last
default double defaultTopKProbability() {
return 0.9999;
}
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 b06022ba714..16d1261b8d6 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
@@ -40,7 +40,6 @@ public class TestProperties implements ModelContext.Properties {
private boolean useDistributorBtreeDb = false;
private boolean useThreePhaseUpdates = false;
private double defaultTermwiseLimit = 1.0;
- private double softStartSeconds = 0.0;
private double threadPoolSizeFactor = 0.0;
private double queueSizeFactor = 0.0;
private Optional<EndpointCertificateSecrets> endpointCertificateSecrets = Optional.empty();
@@ -73,11 +72,6 @@ public class TestProperties implements ModelContext.Properties {
return queueSizeFactor;
}
- @Override
- public double defaultSoftStartSeconds() {
- return softStartSeconds;
- }
-
@Override public boolean useDistributorBtreeDb() { return useDistributorBtreeDb; }
@Override public boolean useThreePhaseUpdates() { return useThreePhaseUpdates; }
@Override public Optional<AthenzDomain> athenzDomain() { return Optional.ofNullable(athenzDomain); }
@@ -98,10 +92,6 @@ public class TestProperties implements ModelContext.Properties {
return this;
}
- public TestProperties setSoftStartSeconds(double softStartSeconds) {
- this.softStartSeconds = softStartSeconds;
- return this;
- }
public TestProperties setThreadPoolSizeFactor(double threadPoolSizeFactor) {
this.threadPoolSizeFactor = threadPoolSizeFactor;
return this;
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 207e130eaaa..5207a0163cb 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
@@ -44,8 +44,8 @@ public final class ApplicationContainer extends Container implements
@Override
public void getConfig(QrStartConfig.Builder builder) {
if (getHostResource() != null) {
- if ( ! getHostResource().advertisedResources().isUnspecified()) {
- NodeResourcesTuning flavorTuning = new NodeResourcesTuning(getHostResource().advertisedResources());
+ if ( ! getHostResource().realResources().isUnspecified()) {
+ NodeResourcesTuning flavorTuning = new NodeResourcesTuning(getHostResource().realResources());
flavorTuning.getConfig(builder);
}
}
@@ -79,13 +79,13 @@ public final class ApplicationContainer extends Container implements
@Override
public void getConfig(ThreadpoolConfig.Builder builder) {
if (! (parent instanceof ContainerCluster)) return;
- if ((getHostResource() == null) || getHostResource().advertisedResources().isUnspecified()) return;
+ if ((getHostResource() == null) || getHostResource().realResources().isUnspecified()) return;
ContainerCluster containerCluster = (ContainerCluster) parent;
if (containerCluster.getThreadPoolSizeFactor() <= 0.0) return;
- NodeResourcesTuning flavorTuning = new NodeResourcesTuning(getHostResource().advertisedResources())
+ NodeResourcesTuning resourcesTuning = new NodeResourcesTuning(getHostResource().realResources())
.setThreadPoolSizeFactor(containerCluster.getThreadPoolSizeFactor())
.setQueueSizeFactor(containerCluster.getQueueSizeFactor());
- flavorTuning.getConfig(builder);
+ resourcesTuning.getConfig(builder);
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
index 37548a15835..56e0bd579cb 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
@@ -69,7 +69,6 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
private MbusParams mbusParams;
private boolean messageBusEnabled = true;
- private final double softStartSeconds;
private Integer memoryPercentage = null;
@@ -87,7 +86,6 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
addSimpleComponent("ai.vespa.cloud.SystemInfo");
addMetricsV2Handler();
addTestrunnerComponentsIfTester(deployState);
- softStartSeconds = deployState.getProperties().defaultSoftStartSeconds();
}
@Override
@@ -254,7 +252,6 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
@Override
public void getConfig(ThreadpoolConfig.Builder builder) {
- builder.softStartSeconds(softStartSeconds);
}
public static class MbusParams {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/StorageNode.java b/config-model/src/main/java/com/yahoo/vespa/model/content/StorageNode.java
index 028aee369c3..f41188eccde 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/StorageNode.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/StorageNode.java
@@ -86,8 +86,8 @@ public class StorageNode extends ContentNode implements StorServerConfig.Produce
@Override
public void getConfig(StorFilestorConfig.Builder builder) {
- if (getHostResource() != null && ! getHostResource().advertisedResources().isUnspecified()) {
- builder.num_threads(Math.max(4, (int)getHostResource().advertisedResources().vcpu()));
+ if (getHostResource() != null && ! getHostResource().realResources().isUnspecified()) {
+ builder.num_threads(Math.max(4, (int)getHostResource().realResources().vcpu()));
}
cluster.getConfig(builder);
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java b/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java
index f908d091a72..c1498936280 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java
@@ -269,19 +269,14 @@ public class SearchNode extends AbstractService implements
// to make sure the node failer has done its work
builder.pruneremoveddocumentsage(4 * 24 * 3600 + 3600 + 60);
}
- if (getHostResource() != null && ! getHostResource().advertisedResources().isUnspecified()) {
- NodeResourcesTuning nodeResourcesTuning = tuning.isPresent()
- ? new NodeResourcesTuning(getHostResource().advertisedResources(), redundancy, searchableCopies, tuning.get().getNumThreadsPerSearch())
- : new NodeResourcesTuning(getHostResource().advertisedResources(), redundancy, searchableCopies);
+ if (getHostResource() != null && ! getHostResource().realResources().isUnspecified()) {
+ var nodeResourcesTuning = tuning.isPresent()
+ ? new NodeResourcesTuning(getHostResource().realResources(), redundancy, searchableCopies, tuning.get().getNumThreadsPerSearch())
+ : new NodeResourcesTuning(getHostResource().realResources(), redundancy, searchableCopies);
nodeResourcesTuning.getConfig(builder);
- if (tuning.isPresent()) {
- tuning.get().getConfig(builder);
- }
-
- if (resourceLimits.isPresent()) {
- resourceLimits.get().getConfig(builder);
- }
+ tuning.ifPresent(t -> t.getConfig(builder));
+ resourceLimits.ifPresent(l -> l.getConfig(builder));
}
}
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 9a59907a230..739ae055ec7 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
@@ -167,7 +167,6 @@ public class ContainerClusterTest {
ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
assertEquals(10, threadpoolConfig.maxthreads());
assertEquals(0, threadpoolConfig.queueSize());
- assertEquals(0, threadpoolConfig.softStartSeconds(), 0);
}
@Test
@@ -206,22 +205,6 @@ public class ContainerClusterTest {
}
@Test
- public void requireThatSoftStartSecondsCanBeControlledByProperties() {
- DeployState state = new DeployState.Builder().properties(new TestProperties().setSoftStartSeconds(300.0))
- .build();
- MockRoot root = new MockRoot("foo", state);
- ApplicationContainerCluster cluster = createContainerCluster(root, false);
- addContainer(root.deployLogger(), cluster, "c1", "host-c1");
-
- ThreadpoolConfig.Builder tpBuilder = new ThreadpoolConfig.Builder();
- cluster.getConfig(tpBuilder);
- ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
- assertEquals(500, threadpoolConfig.maxthreads());
- assertEquals(0, threadpoolConfig.queueSize());
- assertEquals(300.0, threadpoolConfig.softStartSeconds(), 0.0);
- }
-
- @Test
public void requireThatPoolAndQueueCanNotBeControlledByPropertiesWhenNoFlavor() {
DeployState state = new DeployState.Builder().properties(new TestProperties()
.setThreadPoolSizeFactor(8.5)
@@ -236,7 +219,6 @@ public class ContainerClusterTest {
ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
assertEquals(500, threadpoolConfig.maxthreads());
assertEquals(0, threadpoolConfig.queueSize());
- assertEquals(0.0, threadpoolConfig.softStartSeconds(), 0.0);
}
@Test
@@ -251,7 +233,6 @@ public class ContainerClusterTest {
ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
assertEquals(40, threadpoolConfig.maxthreads());
assertEquals(700, threadpoolConfig.queueSize());
- assertEquals(0.0, threadpoolConfig.softStartSeconds(), 0.0);
}
@Test
@@ -265,7 +246,6 @@ public class ContainerClusterTest {
ThreadpoolConfig threadpoolConfig = new ThreadpoolConfig(tpBuilder);
assertEquals(500, threadpoolConfig.maxthreads());
assertEquals(0, threadpoolConfig.queueSize());
- assertEquals(0.0, threadpoolConfig.softStartSeconds(), 0.0);
}
@Test
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index 73c8521d963..3cadb78f15f 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -223,13 +223,6 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
}
}
- public PrepareResult prepareAndActivate(Tenant tenant, long sessionId, PrepareParams prepareParams,
- boolean ignoreSessionStaleFailure, Instant now) {
- PrepareResult result = prepare(tenant, sessionId, prepareParams, now);
- activate(tenant, sessionId, prepareParams.getTimeoutBudget(), ignoreSessionStaleFailure);
- return result;
- }
-
public PrepareResult deploy(CompressedApplicationInputStream in, PrepareParams prepareParams) {
return deploy(in, prepareParams, false, clock.instant());
}
@@ -255,7 +248,9 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
ApplicationId applicationId = prepareParams.getApplicationId();
long sessionId = createSession(applicationId, prepareParams.getTimeoutBudget(), applicationPackage);
Tenant tenant = tenantRepository.getTenant(applicationId.tenant());
- return prepareAndActivate(tenant, sessionId, prepareParams, ignoreSessionStaleFailure, now);
+ PrepareResult result = prepare(tenant, sessionId, prepareParams, now);
+ activate(tenant, sessionId, prepareParams.getTimeoutBudget(), ignoreSessionStaleFailure);
+ return result;
}
/**
@@ -567,7 +562,6 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
return logRetriever.getLogs(logServerURI);
}
-
// ---------------- Methods to do call against tester containers in hosted ------------------------------
public HttpResponse getTesterStatus(ApplicationId applicationId) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
index 6d57239fc4a..288df341f2a 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
@@ -151,7 +151,6 @@ public class ModelContextImpl implements ModelContext {
private final boolean useThreePhaseUpdates;
private final Optional<EndpointCertificateSecrets> endpointCertificateSecrets;
private final double defaultTermwiseLimit;
- private final double defaultSoftStartSeconds;
private final double threadPoolSizeFactor;
private final double queueSizefactor;
private final Optional<AthenzDomain> athenzDomain;
@@ -187,8 +186,6 @@ public class ModelContextImpl implements ModelContext {
this.endpointCertificateSecrets = endpointCertificateSecrets;
defaultTermwiseLimit = Flags.DEFAULT_TERM_WISE_LIMIT.bindTo(flagSource)
.with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value();
- defaultSoftStartSeconds = Flags.DEFAULT_SOFT_START_SECONDS.bindTo(flagSource)
- .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value();
useDistributorBtreeDb = Flags.USE_DISTRIBUTOR_BTREE_DB.bindTo(flagSource)
.with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value();
useThreePhaseUpdates = Flags.USE_THREE_PHASE_UPDATES.bindTo(flagSource)
@@ -256,10 +253,6 @@ public class ModelContextImpl implements ModelContext {
return queueSizefactor;
}
- public double defaultSoftStartSeconds() {
- return defaultSoftStartSeconds;
- }
-
@Override
public boolean useDistributorBtreeDb() {
return useDistributorBtreeDb;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java
index ef510b7dc37..dedd96da6f3 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationApiHandler.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
+import com.yahoo.jdisc.application.BindingMatch;
import com.yahoo.vespa.config.server.ApplicationRepository;
import com.yahoo.vespa.config.server.application.CompressedApplicationInputStream;
import com.yahoo.vespa.config.server.http.SessionHandler;
@@ -18,6 +19,10 @@ import com.yahoo.vespa.config.server.tenant.TenantRepository;
import java.time.Duration;
import java.time.Instant;
+import static com.yahoo.vespa.config.server.application.CompressedApplicationInputStream.createFromCompressedStream;
+import static com.yahoo.vespa.config.server.http.Utils.checkThatTenantExists;
+import static com.yahoo.vespa.config.server.http.v2.SessionCreateHandler.validateDataAndHeader;
+
/**
* * The implementation of the /application/v2 API.
*
@@ -46,31 +51,16 @@ public class ApplicationApiHandler extends SessionHandler {
}
@Override
- protected HttpResponse handlePUT(HttpRequest request) {
- Tenant tenant = getExistingTenant(request);
- TenantName tenantName = tenant.getName();
- long sessionId = getSessionIdV2(request);
- PrepareParams prepareParams = PrepareParams.fromHttpRequest(request, tenantName, zookeeperBarrierTimeout);
-
- PrepareResult result = applicationRepository.prepareAndActivate(tenant, sessionId, prepareParams,
- shouldIgnoreSessionStaleFailure(request),
- Instant.now());
- return new SessionPrepareAndActivateResponse(result, tenantName, request, prepareParams.getApplicationId(), zone);
- }
-
- @Override
protected HttpResponse handlePOST(HttpRequest request) {
- Tenant tenant = getExistingTenant(request);
- TenantName tenantName = tenant.getName();
- PrepareParams prepareParams = PrepareParams.fromHttpRequest(request, tenantName, zookeeperBarrierTimeout);
- SessionCreateHandler.validateDataAndHeader(request);
-
- PrepareResult result =
- applicationRepository.deploy(CompressedApplicationInputStream.createFromCompressedStream(request.getData(), request.getHeader(contentTypeHeader)),
- prepareParams,
- shouldIgnoreSessionStaleFailure(request),
- Instant.now());
- return new SessionPrepareAndActivateResponse(result, tenantName, request, prepareParams.getApplicationId(), zone);
+ validateDataAndHeader(request);
+ Tenant tenant = validateTenant(request);
+ PrepareParams prepareParams = PrepareParams.fromHttpRequest(request, tenant.getName(), zookeeperBarrierTimeout);
+ CompressedApplicationInputStream compressedStream = createFromCompressedStream(request.getData(), request.getHeader(contentTypeHeader));
+ PrepareResult result = applicationRepository.deploy(compressedStream,
+ prepareParams,
+ shouldIgnoreSessionStaleFailure(request),
+ Instant.now());
+ return new SessionPrepareAndActivateResponse(result, request, prepareParams.getApplicationId(), zone);
}
@Override
@@ -78,10 +68,15 @@ public class ApplicationApiHandler extends SessionHandler {
return zookeeperBarrierTimeout.plus(Duration.ofSeconds(10));
}
- private Tenant getExistingTenant(HttpRequest request) {
- TenantName tenantName = Utils.getTenantNameFromSessionRequest(request);
- Utils.checkThatTenantExists(tenantRepository, tenantName);
+ private Tenant validateTenant(HttpRequest request) {
+ TenantName tenantName = getTenantNameFromRequest(request);
+ checkThatTenantExists(tenantRepository, tenantName);
return tenantRepository.getTenant(tenantName);
}
+ public static TenantName getTenantNameFromRequest(HttpRequest request) {
+ BindingMatch<?> bm = Utils.getBindingMatch(request, "http://*/application/v2/tenant/*/prepareandactivate*");
+ return TenantName.from(bm.group(2));
+ }
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java
index 4665a33c647..7d9a0b11c28 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java
@@ -5,8 +5,6 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.jdisc.HttpRequest;
-import com.yahoo.slime.Slime;
-import com.yahoo.vespa.config.server.configchange.ConfigChangeActions;
import com.yahoo.vespa.config.server.configchange.ConfigChangeActionsSlimeConverter;
import com.yahoo.vespa.config.server.http.SessionResponse;
@@ -17,17 +15,10 @@ import com.yahoo.vespa.config.server.http.SessionResponse;
*/
class SessionPrepareAndActivateResponse extends SessionResponse {
- SessionPrepareAndActivateResponse(PrepareResult result, TenantName tenantName, HttpRequest request,
- ApplicationId applicationId, Zone zone) {
- this(result.deployLog(), tenantName, request, result.sessionId(), result.configChangeActions(),
- zone, applicationId);
- }
-
- private SessionPrepareAndActivateResponse(Slime deployLog, TenantName tenantName, HttpRequest request,
- long sessionId, ConfigChangeActions actions, Zone zone,
- ApplicationId applicationId) {
- super(deployLog, deployLog.get());
- String message = "Session " + sessionId + " for tenant '" + tenantName.value() + "' prepared and activated.";
+ SessionPrepareAndActivateResponse(PrepareResult result, HttpRequest request, ApplicationId applicationId, Zone zone) {
+ super(result.deployLog(), result.deployLog().get());
+ TenantName tenantName = applicationId.tenant();
+ String message = "Session " + result.sessionId() + " for tenant '" + tenantName.value() + "' prepared and activated.";
this.root.setString("tenant", tenantName.value());
root.setString("url", "http://" + request.getHost() + ":" + request.getPort() +
"/application/v2/tenant/" + tenantName +
@@ -36,7 +27,7 @@ class SessionPrepareAndActivateResponse extends SessionResponse {
"/region/" + zone.region().value() +
"/instance/" + applicationId.instance().value());
root.setString("message", message);
- new ConfigChangeActionsSlimeConverter(actions).toSlime(root);
+ new ConfigChangeActionsSlimeConverter(result.configChangeActions()).toSlime(root);
}
}
diff --git a/configserver/src/main/resources/configserver-app/services.xml b/configserver/src/main/resources/configserver-app/services.xml
index 0cd283ca62b..d3b39e572ee 100644
--- a/configserver/src/main/resources/configserver-app/services.xml
+++ b/configserver/src/main/resources/configserver-app/services.xml
@@ -106,7 +106,6 @@
</handler>
<handler id='com.yahoo.vespa.config.server.http.v2.ApplicationApiHandler' bundle='configserver'>
<binding>http://*/application/v2/tenant/*/prepareandactivate</binding>
- <binding>http://*/application/v2/tenant/*/session/*/prepareandactivate</binding>
</handler>
<handler id='com.yahoo.vespa.config.server.http.v2.SessionContentHandler' bundle='configserver'>
<binding>http://*/application/v2/tenant/*/session/*/content/*</binding>
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
index ba035ceec59..f37f4b79f99 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
@@ -4,7 +4,6 @@ package com.yahoo.vespa.config.server;
import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.config.application.api.ApplicationMetaData;
import com.yahoo.config.model.api.ApplicationRoles;
-import com.yahoo.config.model.application.provider.FilesApplicationPackage;
import com.yahoo.config.provision.AllocatedHosts;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
@@ -108,8 +107,8 @@ public class ApplicationRepositoryTest {
}
@Test
- public void prepareAndActivate() throws IOException {
- PrepareResult result = prepareAndActivateApp(testApp);
+ public void prepareAndActivate() {
+ PrepareResult result = prepareAndActivate(testApp);
assertTrue(result.configChangeActions().getRefeedActions().isEmpty());
assertTrue(result.configChangeActions().getRestartActions().isEmpty());
@@ -121,9 +120,9 @@ public class ApplicationRepositoryTest {
}
@Test
- public void prepareAndActivateWithRestart() throws IOException {
- prepareAndActivateApp(testAppJdiscOnly);
- PrepareResult result = prepareAndActivateApp(testAppJdiscOnlyRestart);
+ public void prepareAndActivateWithRestart() {
+ prepareAndActivate(testAppJdiscOnly);
+ PrepareResult result = prepareAndActivate(testAppJdiscOnlyRestart);
assertTrue(result.configChangeActions().getRefeedActions().isEmpty());
assertFalse(result.configChangeActions().getRestartActions().isEmpty());
}
@@ -404,8 +403,8 @@ public class ApplicationRepositoryTest {
}
@Test
- public void require_that_provision_info_can_be_read() throws Exception {
- prepareAndActivateApp(testAppJdiscOnly);
+ public void require_that_provision_info_can_be_read() {
+ prepareAndActivate(testAppJdiscOnly);
TenantName tenantName = applicationId().tenant();
Tenant tenant = tenantRepository.getTenant(tenantName);
@@ -455,12 +454,8 @@ public class ApplicationRepositoryTest {
new NullMetric());
}
- private PrepareResult prepareAndActivateApp(File application) throws IOException {
- FilesApplicationPackage appDir = FilesApplicationPackage.fromFile(application);
- ApplicationId applicationId = applicationId();
- long sessionId = applicationRepository.createSession(applicationId, timeoutBudget, appDir.getAppDir());
- return applicationRepository.prepareAndActivate(tenantRepository.getTenant(applicationId.tenant()),
- sessionId, prepareParams(), false, Instant.now());
+ private PrepareResult prepareAndActivate(File application) {
+ return applicationRepository.deploy(application, prepareParams(), false, Instant.now());
}
private PrepareResult deployApp(File applicationPackage) {
diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json
index 82d34d88b99..b4720bd725d 100644
--- a/container-core/abi-spec.json
+++ b/container-core/abi-spec.json
@@ -173,7 +173,6 @@
"public com.yahoo.container.handler.ThreadpoolConfig$Builder maxthreads(int)",
"public com.yahoo.container.handler.ThreadpoolConfig$Builder queueSize(int)",
"public com.yahoo.container.handler.ThreadpoolConfig$Builder maxThreadExecutionTimeSeconds(int)",
- "public com.yahoo.container.handler.ThreadpoolConfig$Builder softStartSeconds(double)",
"public final boolean dispatchGetConfig(com.yahoo.config.ConfigInstance$Producer)",
"public final java.lang.String getDefMd5()",
"public final java.lang.String getDefName()",
@@ -212,8 +211,7 @@
"public void <init>(com.yahoo.container.handler.ThreadpoolConfig$Builder)",
"public int maxthreads()",
"public int queueSize()",
- "public int maxThreadExecutionTimeSeconds()",
- "public double softStartSeconds()"
+ "public int maxThreadExecutionTimeSeconds()"
],
"fields": [
"public static final java.lang.String CONFIG_DEF_MD5",
diff --git a/container-core/src/main/resources/configdefinitions/threadpool.def b/container-core/src/main/resources/configdefinitions/threadpool.def
index abc60f9f06d..81e77c51194 100644
--- a/container-core/src/main/resources/configdefinitions/threadpool.def
+++ b/container-core/src/main/resources/configdefinitions/threadpool.def
@@ -16,8 +16,3 @@ queueSize int default=0
# get out of a bad state. This should be set a bit higher than the expected max execution
# time of each request when in a state of overload, i.e about "worst case execution time*2"
maxThreadExecutionTimeSeconds int default=190
-
-# Length of period for soft start
-# During this period number of availble threads will be gradually increased.
-# Currently used to avoid feeding overload in container during cold start.
-softStartSeconds double default=0
diff --git a/eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp b/eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp
index 3c35f90c521..c8091fd7c6e 100644
--- a/eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp
+++ b/eval/src/tests/eval/tensor_lambda/tensor_lambda_test.cpp
@@ -8,6 +8,7 @@
#include <vespa/eval/tensor/dense/dense_replace_type_function.h>
#include <vespa/eval/tensor/dense/dense_cell_range_function.h>
#include <vespa/eval/tensor/dense/dense_lambda_peek_function.h>
+#include <vespa/eval/tensor/dense/dense_lambda_function.h>
#include <vespa/eval/tensor/dense/dense_fast_rename_optimizer.h>
#include <vespa/eval/tensor/dense/dense_tensor.h>
#include <vespa/eval/eval/test/tensor_model.hpp>
@@ -23,11 +24,27 @@ using namespace vespalib::eval::test;
using namespace vespalib::tensor;
using namespace vespalib::eval::tensor_function;
+using EvalMode = DenseLambdaFunction::EvalMode;
+
+namespace vespalib::tensor {
+
+std::ostream &operator<<(std::ostream &os, EvalMode eval_mode)
+{
+ switch(eval_mode) {
+ case EvalMode::COMPILED: return os << "COMPILED";
+ case EvalMode::INTERPRETED: return os << "INTERPRETED";
+ }
+ abort();
+}
+
+}
+
const TensorEngine &prod_engine = DefaultTensorEngine::ref();
EvalFixture::ParamRepo make_params() {
return EvalFixture::ParamRepo()
.add("a", spec(1))
+ .add("b", spec(2))
.add("x3", spec({x(3)}, N()))
.add("x3f", spec(float_cells({x(3)}), N()))
.add("x3m", spec({x({"0", "1", "2"})}, N()))
@@ -55,8 +72,14 @@ void verify_impl(const vespalib::string &expr, const vespalib::string &expect) {
verify_impl<T>(expr, expect, [](const T*){});
}
-void verify_generic(const vespalib::string &expr, const vespalib::string &expect) {
- verify_impl<Lambda>(expr, expect);
+void verify_generic(const vespalib::string &expr, const vespalib::string &expect,
+ EvalMode expect_eval_mode)
+{
+ verify_impl<DenseLambdaFunction>(expr, expect,
+ [&](const DenseLambdaFunction *info)
+ {
+ EXPECT_EQUAL(info->eval_mode(), expect_eval_mode);
+ });
}
void verify_reshape(const vespalib::string &expr, const vespalib::string &expect) {
@@ -67,8 +90,8 @@ void verify_range(const vespalib::string &expr, const vespalib::string &expect)
verify_impl<DenseCellRangeFunction>(expr, expect);
}
-void verify_compiled(const vespalib::string &expr, const vespalib::string &expect,
- const vespalib::string &expect_idx_fun)
+void verify_idx_fun(const vespalib::string &expr, const vespalib::string &expect,
+ const vespalib::string &expect_idx_fun)
{
verify_impl<DenseLambdaPeekFunction>(expr, expect,
[&](const DenseLambdaPeekFunction *info)
@@ -88,22 +111,32 @@ TEST("require that simple constant tensor lambda works") {
}
TEST("require that simple dynamic tensor lambda works") {
- TEST_DO(verify_generic("tensor(x[3])(x+a)", "tensor(x[3]):[1,2,3]"));
+ TEST_DO(verify_generic("tensor(x[3])(x+a)", "tensor(x[3]):[1,2,3]", EvalMode::COMPILED));
+}
+
+TEST("require that compiled multi-dimensional multi-param dynamic tensor lambda works") {
+ TEST_DO(verify_generic("tensor(x[3],y[2])((b-a)+x+y)", "tensor(x[3],y[2]):[[1,2],[2,3],[3,4]]", EvalMode::COMPILED));
+ TEST_DO(verify_generic("tensor<float>(x[3],y[2])((b-a)+x+y)", "tensor<float>(x[3],y[2]):[[1,2],[2,3],[3,4]]", EvalMode::COMPILED));
+}
+
+TEST("require that interpreted multi-dimensional multi-param dynamic tensor lambda works") {
+ TEST_DO(verify_generic("tensor(x[3],y[2])((x3{x:(a)}-a)+x+y)", "tensor(x[3],y[2]):[[1,2],[2,3],[3,4]]", EvalMode::INTERPRETED));
+ TEST_DO(verify_generic("tensor<float>(x[3],y[2])((x3{x:(a)}-a)+x+y)", "tensor<float>(x[3],y[2]):[[1,2],[2,3],[3,4]]", EvalMode::INTERPRETED));
}
TEST("require that tensor lambda can be used for tensor slicing") {
- TEST_DO(verify_generic("tensor(x[2])(x3{x:(x+a)})", "tensor(x[2]):[2,3]"));
- TEST_DO(verify_generic("tensor(x[2])(a+x3{x:(x)})", "tensor(x[2]):[2,3]"));
+ TEST_DO(verify_generic("tensor(x[2])(x3{x:(x+a)})", "tensor(x[2]):[2,3]", EvalMode::INTERPRETED));
+ TEST_DO(verify_generic("tensor(x[2])(a+x3{x:(x)})", "tensor(x[2]):[2,3]", EvalMode::INTERPRETED));
}
TEST("require that tensor lambda can be used for cell type casting") {
- TEST_DO(verify_compiled("tensor(x[3])(x3f{x:(x)})", "tensor(x[3]):[1,2,3]", "f(x)(x)"));
- TEST_DO(verify_compiled("tensor<float>(x[3])(x3{x:(x)})", "tensor<float>(x[3]):[1,2,3]", "f(x)(x)"));
+ TEST_DO(verify_idx_fun("tensor(x[3])(x3f{x:(x)})", "tensor(x[3]):[1,2,3]", "f(x)(x)"));
+ TEST_DO(verify_idx_fun("tensor<float>(x[3])(x3{x:(x)})", "tensor<float>(x[3]):[1,2,3]", "f(x)(x)"));
}
TEST("require that tensor lambda can be used to convert from sparse to dense tensors") {
- TEST_DO(verify_generic("tensor(x[3])(x3m{x:(x)})", "tensor(x[3]):[1,2,3]"));
- TEST_DO(verify_generic("tensor(x[2])(x3m{x:(x)})", "tensor(x[2]):[1,2]"));
+ TEST_DO(verify_generic("tensor(x[3])(x3m{x:(x)})", "tensor(x[3]):[1,2,3]", EvalMode::INTERPRETED));
+ TEST_DO(verify_generic("tensor(x[2])(x3m{x:(x)})", "tensor(x[2]):[1,2]", EvalMode::INTERPRETED));
}
TEST("require that constant nested tensor lambda using tensor peek works") {
@@ -111,7 +144,7 @@ TEST("require that constant nested tensor lambda using tensor peek works") {
}
TEST("require that dynamic nested tensor lambda using tensor peek works") {
- TEST_DO(verify_generic("tensor(x[2])(tensor(y[2])((x+y)+a){y:(x)})", "tensor(x[2]):[1,3]"));
+ TEST_DO(verify_generic("tensor(x[2])(tensor(y[2])((x+y)+a){y:(x)})", "tensor(x[2]):[1,3]", EvalMode::INTERPRETED));
}
TEST("require that tensor reshape is optimized") {
@@ -121,10 +154,10 @@ TEST("require that tensor reshape is optimized") {
}
TEST("require that tensor reshape with non-matching cell type requires cell copy") {
- TEST_DO(verify_compiled("tensor(x[15])(x3y5f{x:(x/5),y:(x%5)})", "x15", "f(x)((floor((x/5))*5)+(x%5))"));
- TEST_DO(verify_compiled("tensor<float>(x[15])(x3y5{x:(x/5),y:(x%5)})", "x15f", "f(x)((floor((x/5))*5)+(x%5))"));
- TEST_DO(verify_compiled("tensor(x[3],y[5])(x15f{x:(x*5+y)})", "x3y5", "f(x,y)((x*5)+y)"));
- TEST_DO(verify_compiled("tensor<float>(x[3],y[5])(x15{x:(x*5+y)})", "x3y5f", "f(x,y)((x*5)+y)"));
+ TEST_DO(verify_idx_fun("tensor(x[15])(x3y5f{x:(x/5),y:(x%5)})", "x15", "f(x)((floor((x/5))*5)+(x%5))"));
+ TEST_DO(verify_idx_fun("tensor<float>(x[15])(x3y5{x:(x/5),y:(x%5)})", "x15f", "f(x)((floor((x/5))*5)+(x%5))"));
+ TEST_DO(verify_idx_fun("tensor(x[3],y[5])(x15f{x:(x*5+y)})", "x3y5", "f(x,y)((x*5)+y)"));
+ TEST_DO(verify_idx_fun("tensor<float>(x[3],y[5])(x15{x:(x*5+y)})", "x3y5f", "f(x,y)((x*5)+y)"));
}
TEST("require that tensor cell subrange view is optimized") {
@@ -135,22 +168,22 @@ TEST("require that tensor cell subrange view is optimized") {
}
TEST("require that tensor cell subrange with non-matching cell type requires cell copy") {
- TEST_DO(verify_compiled("tensor(x[3])(x15f{x:(x+5)})", "tensor(x[3]):[6,7,8]", "f(x)(x+5)"));
- TEST_DO(verify_compiled("tensor<float>(x[3])(x15{x:(x+5)})", "tensor<float>(x[3]):[6,7,8]", "f(x)(x+5)"));
+ TEST_DO(verify_idx_fun("tensor(x[3])(x15f{x:(x+5)})", "tensor(x[3]):[6,7,8]", "f(x)(x+5)"));
+ TEST_DO(verify_idx_fun("tensor<float>(x[3])(x15{x:(x+5)})", "tensor<float>(x[3]):[6,7,8]", "f(x)(x+5)"));
}
TEST("require that non-continuous cell extraction is optimized") {
- TEST_DO(verify_compiled("tensor(x[3])(x3y5{x:(x),y:2})", "x3y5{y:2}", "f(x)((floor(x)*5)+2)"));
- TEST_DO(verify_compiled("tensor(x[3])(x3y5f{x:(x),y:2})", "x3y5{y:2}", "f(x)((floor(x)*5)+2)"));
- TEST_DO(verify_compiled("tensor<float>(x[3])(x3y5{x:(x),y:2})", "x3y5f{y:2}", "f(x)((floor(x)*5)+2)"));
- TEST_DO(verify_compiled("tensor<float>(x[3])(x3y5f{x:(x),y:2})", "x3y5f{y:2}", "f(x)((floor(x)*5)+2)"));
+ TEST_DO(verify_idx_fun("tensor(x[3])(x3y5{x:(x),y:2})", "x3y5{y:2}", "f(x)((floor(x)*5)+2)"));
+ TEST_DO(verify_idx_fun("tensor(x[3])(x3y5f{x:(x),y:2})", "x3y5{y:2}", "f(x)((floor(x)*5)+2)"));
+ TEST_DO(verify_idx_fun("tensor<float>(x[3])(x3y5{x:(x),y:2})", "x3y5f{y:2}", "f(x)((floor(x)*5)+2)"));
+ TEST_DO(verify_idx_fun("tensor<float>(x[3])(x3y5f{x:(x),y:2})", "x3y5f{y:2}", "f(x)((floor(x)*5)+2)"));
}
TEST("require that out-of-bounds cell extraction is not optimized") {
- TEST_DO(verify_generic("tensor(x[3])(x3y5{x:1,y:(x+3)})", "tensor(x[3]):[9,10,0]"));
- TEST_DO(verify_generic("tensor(x[3])(x3y5{x:1,y:(x-1)})", "tensor(x[3]):[0,6,7]"));
- TEST_DO(verify_generic("tensor(x[3])(x3y5{x:(x+1),y:(x)})", "tensor(x[3]):[6,12,0]"));
- TEST_DO(verify_generic("tensor(x[3])(x3y5{x:(x-1),y:(x)})", "tensor(x[3]):[0,2,8]"));
+ TEST_DO(verify_generic("tensor(x[3])(x3y5{x:1,y:(x+3)})", "tensor(x[3]):[9,10,0]", EvalMode::INTERPRETED));
+ TEST_DO(verify_generic("tensor(x[3])(x3y5{x:1,y:(x-1)})", "tensor(x[3]):[0,6,7]", EvalMode::INTERPRETED));
+ TEST_DO(verify_generic("tensor(x[3])(x3y5{x:(x+1),y:(x)})", "tensor(x[3]):[6,12,0]", EvalMode::INTERPRETED));
+ TEST_DO(verify_generic("tensor(x[3])(x3y5{x:(x-1),y:(x)})", "tensor(x[3]):[0,2,8]", EvalMode::INTERPRETED));
}
TEST("require that non-double result from inner tensor lambda function fails type resolving") {
diff --git a/eval/src/vespa/eval/eval/tensor_function.cpp b/eval/src/vespa/eval/eval/tensor_function.cpp
index 2656e240a5b..1aa18417b87 100644
--- a/eval/src/vespa/eval/eval/tensor_function.cpp
+++ b/eval/src/vespa/eval/eval/tensor_function.cpp
@@ -134,9 +134,16 @@ void op_tensor_create(State &state, uint64_t param) {
state.pop_n_push(i, result);
}
+struct LambdaParams {
+ const Lambda &parent;
+ InterpretedFunction fun;
+ LambdaParams(const Lambda &parent_in, InterpretedFunction fun_in)
+ : parent(parent_in), fun(std::move(fun_in)) {}
+};
+
void op_tensor_lambda(State &state, uint64_t param) {
- const Lambda::Self &self = unwrap_param<Lambda::Self>(param);
- TensorSpec spec = self.parent.create_spec(*state.params, self.fun);
+ const LambdaParams &params = unwrap_param<LambdaParams>(param);
+ TensorSpec spec = params.parent.create_spec(*state.params, params.fun);
const Value &result = *state.stash.create<Value::UP>(state.engine.from_spec(spec));
state.stack.emplace_back(result);
}
@@ -439,13 +446,8 @@ InterpretedFunction::Instruction
Lambda::compile_self(const TensorEngine &engine, Stash &stash) const
{
InterpretedFunction fun(engine, _lambda->root(), _lambda_types);
- Self &self = stash.create<Self>(*this, std::move(fun));
- return Instruction(op_tensor_lambda, wrap_param<Self>(self));
-}
-
-void
-Lambda::push_children(std::vector<Child::CREF> &) const
-{
+ LambdaParams &params = stash.create<LambdaParams>(*this, std::move(fun));
+ return Instruction(op_tensor_lambda, wrap_param<LambdaParams>(params));
}
void
diff --git a/eval/src/vespa/eval/eval/tensor_function.h b/eval/src/vespa/eval/eval/tensor_function.h
index e1961079017..6743f37eeb1 100644
--- a/eval/src/vespa/eval/eval/tensor_function.h
+++ b/eval/src/vespa/eval/eval/tensor_function.h
@@ -183,7 +183,7 @@ class ConstValue : public Leaf
private:
const Value &_value;
public:
- ConstValue(const Value &value_in) : Leaf(value_in.type()), _value(value_in) {}
+ ConstValue(const Value &value_in) : Super(value_in.type()), _value(value_in) {}
const Value &value() const { return _value; }
bool result_is_mutable() const override { return false; }
InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
@@ -199,7 +199,7 @@ private:
size_t _param_idx;
public:
Inject(const ValueType &result_type_in, size_t param_idx_in)
- : Leaf(result_type_in), _param_idx(param_idx_in) {}
+ : Super(result_type_in), _param_idx(param_idx_in) {}
size_t param_idx() const { return _param_idx; }
bool result_is_mutable() const override { return false; }
InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
@@ -219,7 +219,7 @@ public:
const TensorFunction &child_in,
Aggr aggr_in,
const std::vector<vespalib::string> &dimensions_in)
- : Op1(result_type_in, child_in), _aggr(aggr_in), _dimensions(dimensions_in) {}
+ : Super(result_type_in, child_in), _aggr(aggr_in), _dimensions(dimensions_in) {}
Aggr aggr() const { return _aggr; }
const std::vector<vespalib::string> &dimensions() const { return _dimensions; }
bool result_is_mutable() const override { return true; }
@@ -238,7 +238,7 @@ public:
Map(const ValueType &result_type_in,
const TensorFunction &child_in,
map_fun_t function_in)
- : Op1(result_type_in, child_in), _function(function_in) {}
+ : Super(result_type_in, child_in), _function(function_in) {}
map_fun_t function() const { return _function; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const override;
@@ -257,7 +257,7 @@ public:
const TensorFunction &lhs_in,
const TensorFunction &rhs_in,
join_fun_t function_in)
- : Op2(result_type_in, lhs_in, rhs_in), _function(function_in) {}
+ : Super(result_type_in, lhs_in, rhs_in), _function(function_in) {}
join_fun_t function() const { return _function; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const override;
@@ -276,7 +276,7 @@ public:
const TensorFunction &lhs_in,
const TensorFunction &rhs_in,
join_fun_t function_in)
- : Op2(result_type_in, lhs_in, rhs_in), _function(function_in) {}
+ : Super(result_type_in, lhs_in, rhs_in), _function(function_in) {}
join_fun_t function() const { return _function; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const override;
@@ -295,7 +295,7 @@ public:
const TensorFunction &lhs_in,
const TensorFunction &rhs_in,
const vespalib::string &dimension_in)
- : Op2(result_type_in, lhs_in, rhs_in), _dimension(dimension_in) {}
+ : Super(result_type_in, lhs_in, rhs_in), _dimension(dimension_in) {}
const vespalib::string &dimension() const { return _dimension; }
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
@@ -311,7 +311,7 @@ private:
std::map<TensorSpec::Address, Child> _spec;
public:
Create(const ValueType &result_type_in, const std::map<TensorSpec::Address, Node::CREF> &spec_in)
- : Node(result_type_in), _spec()
+ : Super(result_type_in), _spec()
{
for (const auto &cell: spec_in) {
_spec.emplace(cell.first, Child(cell.second));
@@ -326,23 +326,16 @@ public:
//-----------------------------------------------------------------------------
-class Lambda : public Node
+class Lambda : public Leaf
{
- using Super = Node;
-public:
- struct Self {
- const Lambda &parent;
- InterpretedFunction fun;
- Self(const Lambda &parent_in, InterpretedFunction fun_in)
- : parent(parent_in), fun(std::move(fun_in)) {}
- };
+ using Super = Leaf;
private:
std::vector<size_t> _bindings;
std::shared_ptr<Function const> _lambda;
NodeTypes _lambda_types;
public:
Lambda(const ValueType &result_type_in, const std::vector<size_t> &bindings_in, const Function &lambda_in, NodeTypes lambda_types_in)
- : Node(result_type_in), _bindings(bindings_in), _lambda(lambda_in.shared_from_this()), _lambda_types(std::move(lambda_types_in)) {}
+ : Super(result_type_in), _bindings(bindings_in), _lambda(lambda_in.shared_from_this()), _lambda_types(std::move(lambda_types_in)) {}
const std::vector<size_t> &bindings() const { return _bindings; }
const Function &lambda() const { return *_lambda; }
const NodeTypes &types() const { return _lambda_types; }
@@ -352,7 +345,6 @@ public:
}
bool result_is_mutable() const override { return true; }
InterpretedFunction::Instruction compile_self(const TensorEngine &engine, Stash &stash) const final override;
- void push_children(std::vector<Child::CREF> &children) const final override;
void visit_self(vespalib::ObjectVisitor &visitor) const override;
};
@@ -369,7 +361,7 @@ private:
public:
Peek(const ValueType &result_type_in, const Node &param,
const std::map<vespalib::string, std::variant<TensorSpec::Label, Node::CREF>> &spec)
- : Node(result_type_in), _param(param), _spec()
+ : Super(result_type_in), _param(param), _spec()
{
for (const auto &dim: spec) {
std::visit(vespalib::overload
@@ -404,7 +396,7 @@ public:
const TensorFunction &child_in,
const std::vector<vespalib::string> &from_in,
const std::vector<vespalib::string> &to_in)
- : Op1(result_type_in, child_in), _from(from_in), _to(to_in) {}
+ : Super(result_type_in, child_in), _from(from_in), _to(to_in) {}
const std::vector<vespalib::string> &from() const { return _from; }
const std::vector<vespalib::string> &to() const { return _to; }
bool result_is_mutable() const override { return true; }
diff --git a/eval/src/vespa/eval/tensor/default_tensor_engine.cpp b/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
index d28e420e6f2..d374848af64 100644
--- a/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
+++ b/eval/src/vespa/eval/tensor/default_tensor_engine.cpp
@@ -17,6 +17,7 @@
#include "dense/dense_single_reduce_function.h"
#include "dense/dense_remove_dimension_optimizer.h"
#include "dense/dense_lambda_peek_optimizer.h"
+#include "dense/dense_lambda_function.h"
#include "dense/dense_simple_join_function.h"
#include "dense/dense_simple_map_function.h"
#include "dense/vector_from_doubles_function.h"
@@ -289,6 +290,7 @@ DefaultTensorEngine::optimize(const TensorFunction &expr, Stash &stash) const
child.set(DenseTensorCreateFunction::optimize(child.get(), stash));
child.set(DenseTensorPeekFunction::optimize(child.get(), stash));
child.set(DenseLambdaPeekOptimizer::optimize(child.get(), stash));
+ child.set(DenseLambdaFunction::optimize(child.get(), stash));
child.set(DenseFastRenameOptimizer::optimize(child.get(), stash));
child.set(DenseSimpleMapFunction::optimize(child.get(), stash));
child.set(DenseSimpleJoinFunction::optimize(child.get(), stash));
diff --git a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt
index e0e73ecb3b8..7ababbee228 100644
--- a/eval/src/vespa/eval/tensor/dense/CMakeLists.txt
+++ b/eval/src/vespa/eval/tensor/dense/CMakeLists.txt
@@ -6,6 +6,7 @@ vespa_add_library(eval_tensor_dense OBJECT
dense_dimension_combiner.cpp
dense_dot_product_function.cpp
dense_fast_rename_optimizer.cpp
+ dense_lambda_function.cpp
dense_lambda_peek_function.cpp
dense_lambda_peek_optimizer.cpp
dense_matmul_function.cpp
diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp
new file mode 100644
index 00000000000..b60d732d7a9
--- /dev/null
+++ b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.cpp
@@ -0,0 +1,189 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "dense_lambda_function.h"
+#include "dense_tensor_view.h"
+#include <vespa/vespalib/objects/objectvisitor.h>
+#include <vespa/eval/tensor/default_tensor_engine.h>
+#include <vespa/eval/eval/llvm/compiled_function.h>
+#include <vespa/eval/eval/llvm/compile_cache.h>
+#include <assert.h>
+
+namespace vespalib::tensor {
+
+using eval::CompileCache;
+using eval::CompiledFunction;
+using eval::InterpretedFunction;
+using eval::LazyParams;
+using eval::PassParams;
+using eval::TensorEngine;
+using eval::TensorFunction;
+using eval::Value;
+using eval::DoubleValue;
+using eval::ValueType;
+using eval::as;
+using vespalib::Stash;
+
+using Instruction = InterpretedFunction::Instruction;
+using State = InterpretedFunction::State;
+
+using namespace eval::tensor_function;
+
+const TensorEngine &prod_engine = DefaultTensorEngine::ref();
+
+namespace {
+
+//-----------------------------------------------------------------------------
+
+bool step_labels(double *labels, const ValueType &type) {
+ for (size_t idx = type.dimensions().size(); idx-- > 0; ) {
+ if ((labels[idx] += 1.0) < type.dimensions()[idx].size) {
+ return true;
+ } else {
+ labels[idx] = 0.0;
+ }
+ }
+ return false;
+}
+
+struct ParamProxy : public LazyParams {
+ const std::vector<double> &labels;
+ const LazyParams &params;
+ const std::vector<size_t> &bindings;
+ ParamProxy(const std::vector<double> &labels_in, const LazyParams &params_in, const std::vector<size_t> &bindings_in)
+ : labels(labels_in), params(params_in), bindings(bindings_in) {}
+ const Value &resolve(size_t idx, Stash &stash) const override {
+ if (idx < labels.size()) {
+ return stash.create<DoubleValue>(labels[idx]);
+ }
+ return params.resolve(bindings[idx - labels.size()], stash);
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+struct CompiledParams {
+ const ValueType &result_type;
+ const std::vector<size_t> &bindings;
+ size_t num_cells;
+ CompileCache::Token::UP token;
+ CompiledParams(const Lambda &lambda)
+ : result_type(lambda.result_type()),
+ bindings(lambda.bindings()),
+ num_cells(result_type.dense_subspace_size()),
+ token(CompileCache::compile(lambda.lambda(), PassParams::ARRAY))
+ {
+ assert(lambda.lambda().num_params() == (result_type.dimensions().size() + bindings.size()));
+ }
+};
+
+template <typename CT>
+void my_compiled_lambda_op(eval::InterpretedFunction::State &state, uint64_t param) {
+ const CompiledParams &params = *(const CompiledParams*)param;
+ std::vector<double> args(params.result_type.dimensions().size() + params.bindings.size(), 0.0);
+ double *bind_next = &args[params.result_type.dimensions().size()];
+ for (size_t binding: params.bindings) {
+ *bind_next++ = state.params->resolve(binding, state.stash).as_double();
+ }
+ auto fun = params.token->get().get_function();
+ ArrayRef<CT> dst_cells = state.stash.create_array<CT>(params.num_cells);
+ CT *dst = &dst_cells[0];
+ do {
+ *dst++ = fun(&args[0]);
+ } while (step_labels(&args[0], params.result_type));
+ state.stack.push_back(state.stash.create<DenseTensorView>(params.result_type, TypedCells(dst_cells)));
+}
+
+struct MyCompiledLambdaOp {
+ template <typename CT>
+ static auto get_fun() { return my_compiled_lambda_op<CT>; }
+};
+
+//-----------------------------------------------------------------------------
+
+struct InterpretedParams {
+ const ValueType &result_type;
+ const std::vector<size_t> &bindings;
+ size_t num_cells;
+ InterpretedFunction fun;
+ InterpretedParams(const Lambda &lambda)
+ : result_type(lambda.result_type()),
+ bindings(lambda.bindings()),
+ num_cells(result_type.dense_subspace_size()),
+ fun(prod_engine, lambda.lambda().root(), lambda.types())
+ {
+ assert(lambda.lambda().num_params() == (result_type.dimensions().size() + bindings.size()));
+ }
+};
+
+template <typename CT>
+void my_interpreted_lambda_op(eval::InterpretedFunction::State &state, uint64_t param) {
+ const InterpretedParams &params = *(const InterpretedParams*)param;
+ std::vector<double> labels(params.result_type.dimensions().size(), 0.0);
+ ParamProxy param_proxy(labels, *state.params, params.bindings);
+ InterpretedFunction::Context ctx(params.fun);
+ ArrayRef<CT> dst_cells = state.stash.create_array<CT>(params.num_cells);
+ CT *dst = &dst_cells[0];
+ do {
+ *dst++ = params.fun.eval(ctx, param_proxy).as_double();
+ } while (step_labels(&labels[0], params.result_type));
+ state.stack.push_back(state.stash.create<DenseTensorView>(params.result_type, TypedCells(dst_cells)));
+}
+
+struct MyInterpretedLambdaOp {
+ template <typename CT>
+ static auto get_fun() { return my_interpreted_lambda_op<CT>; }
+};
+
+//-----------------------------------------------------------------------------
+
+}
+
+DenseLambdaFunction::DenseLambdaFunction(const Lambda &lambda_in)
+ : Super(lambda_in.result_type()),
+ _lambda(lambda_in)
+{
+}
+
+DenseLambdaFunction::~DenseLambdaFunction() = default;
+
+DenseLambdaFunction::EvalMode
+DenseLambdaFunction::eval_mode() const
+{
+ if (!CompiledFunction::detect_issues(_lambda.lambda()) &&
+ _lambda.types().all_types_are_double())
+ {
+ return EvalMode::COMPILED;
+ } else {
+ return EvalMode::INTERPRETED;
+ }
+}
+
+Instruction
+DenseLambdaFunction::compile_self(const TensorEngine &engine, Stash &stash) const
+{
+ assert(&engine == &prod_engine);
+ auto mode = eval_mode();
+ if (mode == EvalMode::COMPILED) {
+ CompiledParams &params = stash.create<CompiledParams>(_lambda);
+ auto op = select_1<MyCompiledLambdaOp>(result_type().cell_type());
+ static_assert(sizeof(&params) == sizeof(uint64_t));
+ return Instruction(op, (uint64_t)(&params));
+ } else {
+ assert(mode == EvalMode::INTERPRETED);
+ InterpretedParams &params = stash.create<InterpretedParams>(_lambda);
+ auto op = select_1<MyInterpretedLambdaOp>(result_type().cell_type());
+ static_assert(sizeof(&params) == sizeof(uint64_t));
+ return Instruction(op, (uint64_t)(&params));
+ }
+}
+
+const eval::TensorFunction &
+DenseLambdaFunction::optimize(const TensorFunction &expr, Stash &stash)
+{
+ if (auto lambda = as<Lambda>(expr)) {
+ return stash.create<DenseLambdaFunction>(*lambda);
+ }
+ return expr;
+}
+
+}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h
new file mode 100644
index 00000000000..a1b6e5a1551
--- /dev/null
+++ b/eval/src/vespa/eval/tensor/dense/dense_lambda_function.h
@@ -0,0 +1,30 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/eval/eval/tensor_function.h>
+
+namespace vespalib::tensor {
+
+/**
+ * Tensor function for generic tensor lambda producing dense tensor
+ * views directly. This is the catch-all fall-back used by the default
+ * (production) tensor engine to avoid having a TensorSpec as an
+ * intermediate result.
+ **/
+class DenseLambdaFunction : public eval::tensor_function::Leaf
+{
+ using Super = eval::tensor_function::Leaf;
+private:
+ const eval::tensor_function::Lambda &_lambda;
+public:
+ enum class EvalMode : uint8_t { COMPILED, INTERPRETED };
+ DenseLambdaFunction(const eval::tensor_function::Lambda &lambda_in);
+ ~DenseLambdaFunction() override;
+ bool result_is_mutable() const override { return true; }
+ EvalMode eval_mode() const;
+ eval::InterpretedFunction::Instruction compile_self(const eval::TensorEngine &engine, Stash &stash) const override;
+ static const eval::TensorFunction &optimize(const eval::TensorFunction &expr, Stash &stash);
+};
+
+}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
index 552878de68a..59926355bda 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -136,11 +136,6 @@ public class Flags {
"Takes effect at redeployment",
ZONE_ID, APPLICATION_ID);
- public static final UnboundDoubleFlag DEFAULT_SOFT_START_SECONDS = defineDoubleFlag(
- "default-soft-start-seconds", 0.0,
- "Default number of seconds that a soft start shall use",
- "Takes effect at redeployment",
- ZONE_ID, APPLICATION_ID);
public static final UnboundDoubleFlag DEFAULT_THREADPOOL_SIZE_FACTOR = defineDoubleFlag(
"default-threadpool-size-factor", 0.0,
"Default multiplication factor when computing maxthreads for main container threadpool based on available cores",
@@ -246,7 +241,7 @@ public class Flags {
APPLICATION_ID);
public static final UnboundLongFlag CONFIGSERVER_SESSIONS_EXPIRY_INTERVAL_IN_DAYS = defineLongFlag(
- "configserver-sessions-expiry-interval-in-days", 28,
+ "configserver-sessions-expiry-interval-in-days", 1,
"Expiry time for unused sessions in config server",
"Takes effect on next run of config server maintainer SessionsMaintainer");
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/DiskSize.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/DiskSize.java
index 40a11f61d3f..c76c872902d 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/DiskSize.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/DiskSize.java
@@ -13,10 +13,11 @@ public class DiskSize {
private static final char[] UNITS = "kMGTPE".toCharArray();
public enum Unit {
- kB(1000), kiB(1 << 10),
+ kB(1_000), kiB(1 << 10),
MB(1_000_000), MiB(1 << 20),
GB(1_000_000_000), GiB(1 << 30),
- PB(1_000_000_000_000L), PiB(1L << 40);
+ TB(1_000_000_000_000L), TiB(1L << 40),
+ PB(1_000_000_000_000_000L), PiB(1L << 50);
private final long size;
Unit(long size) { this.size = size; }
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
index 59dbe4bb8d4..e6cbddf96f2 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java
@@ -132,37 +132,30 @@ public class AllocatableClusterResources {
.withBandwidthGbps(sum.bandwidthGbps() / nodes.size());
}
- /**
- * Returns the best matching allocatable node resources given ideal node resources,
- * or empty if none available within the limits.
- *
- * @param resources the real resources that should ideally be allocated
- * @param exclusive whether resources should be allocated on entire hosts
- * (in which case the allocated resources will be all the real resources of the host
- * and limits are required to encompass the full resources of candidate host flavors)
- */
- public static Optional<AllocatableClusterResources> from(ClusterResources resources,
+ public static Optional<AllocatableClusterResources> from(ClusterResources wantedResources,
boolean exclusive,
ClusterSpec.Type clusterType,
- Limits limits,
+ Limits applicationLimits,
NodeRepository nodeRepository) {
- NodeResources cappedNodeResources = limits.cap(resources.nodeResources());
- cappedNodeResources = new NodeResourceLimits(nodeRepository).enlargeToLegal(cappedNodeResources, clusterType);
-
+ var systemLimits = new NodeResourceLimits(nodeRepository);
if ( !exclusive && nodeRepository.zone().getCloud().allowHostSharing()) { // Check if any flavor can fit these hosts
// We decide resources: Add overhead to what we'll request (advertised) to make sure real becomes (at least) cappedNodeResources
- NodeResources realResources = cappedNodeResources;
- NodeResources advertisedResources = nodeRepository.resourcesCalculator().realToRequest(realResources);
+ NodeResources advertisedResources = nodeRepository.resourcesCalculator().realToRequest(wantedResources.nodeResources());
+ advertisedResources = systemLimits.enlargeToLegal(advertisedResources, clusterType); // Attempt to ask for something legal
+ advertisedResources = applicationLimits.cap(advertisedResources); // Overrides other conditions, even if it will then fail
+ NodeResources realResources = nodeRepository.resourcesCalculator().requestToReal(advertisedResources); // ... thus, what we really get may change
+ if ( ! systemLimits.isWithinRealLimits(realResources, clusterType)) return Optional.empty();
for (Flavor flavor : nodeRepository.flavors().getFlavors()) {
if (flavor.resources().satisfies(advertisedResources))
- return Optional.of(new AllocatableClusterResources(resources.with(realResources),
+ return Optional.of(new AllocatableClusterResources(wantedResources.with(realResources),
advertisedResources,
- resources.nodeResources(),
+ wantedResources.nodeResources(),
clusterType));
}
return Optional.empty();
}
else { // Return the cheapest flavor satisfying the requested resources, if any
+ NodeResources cappedWantedResources = applicationLimits.cap(wantedResources.nodeResources());
Optional<AllocatableClusterResources> best = Optional.empty();
for (Flavor flavor : nodeRepository.flavors().getFlavors()) {
// Flavor decide resources: Real resources are the worst case real resources we'll get if we ask for these advertised resources
@@ -171,18 +164,19 @@ public class AllocatableClusterResources {
// Adjust where we don't need exact match to the flavor
if (flavor.resources().storageType() == NodeResources.StorageType.remote) {
- advertisedResources = advertisedResources.withDiskGb(cappedNodeResources.diskGb());
- realResources = realResources.withDiskGb(cappedNodeResources.diskGb());
+ advertisedResources = advertisedResources.withDiskGb(cappedWantedResources.diskGb());
+ realResources = realResources.withDiskGb(cappedWantedResources.diskGb());
}
- if (flavor.resources().bandwidthGbps() >= cappedNodeResources.bandwidthGbps()) {
- advertisedResources = advertisedResources.withBandwidthGbps(cappedNodeResources.bandwidthGbps());
- realResources = realResources.withBandwidthGbps(cappedNodeResources.bandwidthGbps());
+ if (flavor.resources().bandwidthGbps() >= advertisedResources.bandwidthGbps()) {
+ advertisedResources = advertisedResources.withBandwidthGbps(cappedWantedResources.bandwidthGbps());
+ realResources = realResources.withBandwidthGbps(cappedWantedResources.bandwidthGbps());
}
- if ( ! between(limits.min().nodeResources(), limits.max().nodeResources(), advertisedResources)) continue;
- var candidate = new AllocatableClusterResources(resources.with(realResources),
+ if ( ! between(applicationLimits.min().nodeResources(), applicationLimits.max().nodeResources(), advertisedResources)) continue;
+ if ( ! systemLimits.isWithinRealLimits(realResources, clusterType)) continue;
+ var candidate = new AllocatableClusterResources(wantedResources.with(realResources),
advertisedResources,
- resources.nodeResources(),
+ wantedResources.nodeResources(),
clusterType);
if (best.isEmpty() || candidate.preferableTo(best.get()))
best = Optional.of(candidate);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java
index fc68deba957..b2c57e984eb 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java
@@ -39,7 +39,7 @@ public class InactiveExpirer extends Expirer {
@Override
protected void expire(List<Node> expired) {
expired.forEach(node -> {
- if (retiredByOperator(node)) {
+ if (node.status().wantToDeprovision() || retiredByOperator(node)) {
nodeRepository.park(node.hostname(), false, Agent.InactiveExpirer, "Expired by InactiveExpirer");
} else {
nodeRepository.setDirty(node, Agent.InactiveExpirer, "Expired by InactiveExpirer");
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java
index db54fd316f6..06085caa2ee 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java
@@ -35,12 +35,17 @@ public class NodeResourceLimits {
/** Returns whether the real resources we'll end up with on a given tenant node are within limits */
public boolean isWithinRealLimits(Node candidateTenantNode, ClusterSpec cluster) {
- NodeResources realResources = nodeRepository.resourcesCalculator().realResourcesOf(candidateTenantNode, nodeRepository);
+ return isWithinRealLimits(nodeRepository.resourcesCalculator().realResourcesOf(candidateTenantNode, nodeRepository),
+ cluster.type());
+ }
- if (realResources.memoryGb() < minRealMemoryGb(cluster.type())) return false;
- if (realResources.diskGb() < minRealDiskGb()) return false;
+ /** Returns whether the real resources we'll end up with on a given tenant node are within limits */
+ public boolean isWithinRealLimits(NodeResources realResources, ClusterSpec.Type clusterType) {
+ if (realResources.isUnspecified()) return true;
- return true;
+ if (realResources.memoryGb() < minRealMemoryGb(clusterType)) return false;
+ if (realResources.diskGb() < minRealDiskGb()) return false;
+ return true;
}
public NodeResources enlargeToLegal(NodeResources requested, ClusterSpec.Type clusterType) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
index 864cfad2f41..cc5c6851a92 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java
@@ -277,16 +277,16 @@ public class AutoscalingTest {
@Test
public void autoscaling_avoids_illegal_configurations() {
- NodeResources resources = new NodeResources(3, 100, 100, 1);
+ NodeResources hostResources = new NodeResources(3, 100, 100, 1);
ClusterResources min = new ClusterResources( 2, 1, new NodeResources(1, 1, 1, 1));
ClusterResources max = new ClusterResources(20, 1, new NodeResources(100, 1000, 1000, 1));
- AutoscalingTester tester = new AutoscalingTester(resources);
+ AutoscalingTester tester = new AutoscalingTester(hostResources);
ApplicationId application1 = tester.applicationId("application1");
ClusterSpec cluster1 = tester.clusterSpec(ClusterSpec.Type.content, "cluster1");
// deploy
- tester.deploy(application1, cluster1, 6, 1, resources);
+ tester.deploy(application1, cluster1, 6, 1, hostResources);
tester.addMeasurements(Resource.memory, 0.02f, 0.95f, 120, application1);
tester.assertResources("Scaling down",
6, 1, 2.8, 4.0, 95.0,
@@ -325,7 +325,7 @@ public class AutoscalingTest {
tester.addMeasurements(Resource.memory, 1.0f, 1000, application1);
tester.addMeasurements(Resource.disk, 0.7f, 1000, application1);
tester.assertResources("Scaling up",
- 4, 1, 7.0, 35, 200,
+ 4, 1, 7.0, 34, 200,
tester.autoscale(application1, cluster1.id(), min, max));
}
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
index 963ca0d4341..b0e394c93d3 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java
@@ -178,11 +178,12 @@ class AutoscalingTester {
Optional<ClusterResources> resources) {
double delta = 0.0000000001;
assertTrue(message, resources.isPresent());
- assertEquals("Node count: " + message, nodeCount, resources.get().nodes());
- assertEquals("Group count: " + message, groupCount, resources.get().groups());
- assertEquals("Cpu: " + message, approxCpu, Math.round(resources.get().nodeResources().vcpu() * 10) / 10.0, delta);
- assertEquals("Memory: " + message, approxMemory, Math.round(resources.get().nodeResources().memoryGb() * 10) / 10.0, delta);
- assertEquals("Disk: " + message, approxDisk, Math.round(resources.get().nodeResources().diskGb() * 10) / 10.0, delta);
+ NodeResources nodeResources = resources.get().nodeResources();
+ assertEquals("Node count in " + resources.get() + ": " + message, nodeCount, resources.get().nodes());
+ assertEquals("Group count in " + resources.get() + ": " + message, groupCount, resources.get().groups());
+ assertEquals("Cpu in " + resources.get() + ": " + message, approxCpu, Math.round(nodeResources.vcpu() * 10) / 10.0, delta);
+ assertEquals("Memory in " + resources.get() + ": " + message, approxMemory, Math.round(nodeResources.memoryGb() * 10) / 10.0, delta);
+ assertEquals("Disk in: " + resources.get() + ": " + message, approxDisk, Math.round(nodeResources.diskGb() * 10) / 10.0, delta);
return resources.get();
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
index 4fcd5793b8a..e42e8e57b8c 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
@@ -19,7 +19,6 @@ import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.History;
import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester;
import com.yahoo.vespa.hosted.provision.testutils.MockDeployer;
-import com.yahoo.vespa.hosted.provision.testutils.MockNodeMetrics;
import com.yahoo.vespa.orchestrator.OrchestrationException;
import com.yahoo.vespa.orchestrator.Orchestrator;
import org.junit.Test;
@@ -52,7 +51,7 @@ public class InactiveAndFailedExpirerTest {
@Test
public void inactive_and_failed_times_out() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
- List<Node> nodes = tester.makeReadyNodes(2, nodeResources);
+ tester.makeReadyNodes(2, nodeResources);
// Allocate then deallocate 2 nodes
ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test")).vespaVersion("6.42").build();
@@ -90,7 +89,7 @@ public class InactiveAndFailedExpirerTest {
@Test
public void reboot_generation_is_increased_when_node_moves_to_dirty() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
- List<Node> nodes = tester.makeReadyNodes(2, nodeResources);
+ tester.makeReadyNodes(2, nodeResources);
// Allocate and deallocate a single node
ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test")).vespaVersion("6.42").build();
@@ -164,7 +163,7 @@ public class InactiveAndFailedExpirerTest {
}
@Test
- public void testersExpireImmediately() {
+ public void tester_applications_expire_immediately() {
ApplicationId testerId = ApplicationId.from(applicationId.tenant().value(),
applicationId.application().value(),
applicationId.instance().value() + "-t");
@@ -189,4 +188,27 @@ public class InactiveAndFailedExpirerTest {
}
+ @Test
+ public void nodes_marked_for_deprovisioning_move_to_parked() {
+ ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
+ tester.makeReadyNodes(5, nodeResources);
+
+ // Activate and deallocate
+ ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test")).vespaVersion("6.42").build();
+ List<HostSpec> preparedNodes = tester.prepare(applicationId, cluster, Capacity.from(new ClusterResources(2, 1, nodeResources)));
+ tester.activate(applicationId, new HashSet<>(preparedNodes));
+ assertEquals(2, tester.getNodes(applicationId, Node.State.active).size());
+ tester.deactivate(applicationId);
+ List<Node> inactiveNodes = tester.getNodes(applicationId, Node.State.inactive).asList();
+ assertEquals(2, inactiveNodes.size());
+
+ // Nodes marked for deprovisioning are moved to parked
+ tester.nodeRepository().write(inactiveNodes.stream()
+ .map(node -> node.with(node.status().withWantToDeprovision(true)))
+ .collect(Collectors.toList()), () -> {});
+ tester.advanceTime(Duration.ofMinutes(11));
+ new InactiveExpirer(tester.nodeRepository(), tester.clock(), Duration.ofMinutes(10)).run();
+ assertEquals(2, tester.nodeRepository().getNodes(Node.State.parked).size());
+ }
+
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
index 3c1cace3dac..3ffb0dc34f0 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
@@ -8,6 +8,7 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeResources;
@@ -301,6 +302,50 @@ public class DockerProvisioningTest {
}
}
+ @Test
+ public void initial_allocation_is_within_limits() {
+ Flavor hostFlavor = new Flavor(new NodeResources(20, 40, 100, 4));
+ ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east")))
+ .resourcesCalculator(3, 0)
+ .flavors(List.of(hostFlavor))
+ .build();
+ tester.makeReadyHosts(2, hostFlavor.resources()).deployZoneApp();
+
+ ApplicationId app1 = tester.makeApplicationId("app1");
+ ClusterSpec cluster1 = ClusterSpec.request(ClusterSpec.Type.content, new ClusterSpec.Id("cluster1")).vespaVersion("7").build();
+
+ var resources = new NodeResources(1, 8, 10, 1);
+ tester.activate(app1, cluster1, Capacity.from(new ClusterResources(2, 1, resources),
+ new ClusterResources(4, 1, resources)));
+ tester.assertNodes("Initial allocation at min with default resources",
+ 2, 1, 1, 8, 10, 1.0,
+ app1, cluster1);
+ }
+
+ @Test
+ public void too_few_real_resources_causes_failure() {
+ try {
+ Flavor hostFlavor = new Flavor(new NodeResources(20, 40, 100, 4));
+ ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east")))
+ .resourcesCalculator(3, 0)
+ .flavors(List.of(hostFlavor))
+ .build();
+ tester.makeReadyHosts(2, hostFlavor.resources()).deployZoneApp();
+
+ ApplicationId app1 = tester.makeApplicationId("app1");
+ ClusterSpec cluster1 = ClusterSpec.request(ClusterSpec.Type.content, new ClusterSpec.Id("cluster1")).vespaVersion("7").build();
+
+ // 5 Gb requested memory becomes 5-3=2 Gb real memory, which is an illegally small amount
+ var resources = new NodeResources(1, 5, 10, 1);
+ tester.activate(app1, cluster1, Capacity.from(new ClusterResources(2, 1, resources),
+ new ClusterResources(4, 1, resources)));
+ }
+ catch (IllegalArgumentException e) {
+ assertEquals("No allocation possible within limits: from 2 nodes with [vcpu: 1.0, memory: 5.0 Gb, disk 10.0 Gb, bandwidth: 1.0 Gbps] to 4 nodes with [vcpu: 1.0, memory: 5.0 Gb, disk 10.0 Gb, bandwidth: 1.0 Gbps]",
+ e.getMessage());
+ }
+ }
+
private Set<String> hostsOf(NodeList nodes) {
return nodes.asList().stream().map(Node::parentHostname).map(Optional::get).collect(Collectors.toSet());
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
index 25387a2746c..db6d75d724e 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
@@ -19,7 +19,6 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.hosted.provision.Node;
-import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.IP;
import com.yahoo.vespa.hosted.provision.testutils.MockNameResolver;
@@ -168,7 +167,7 @@ public class DynamicDockerProvisionTest {
.flavors(flavors)
.hostProvisioner(new MockHostProvisioner(flavors, memoryTax))
.nameResolver(nameResolver)
- .resourcesCalculator(new MockResourcesCalculator(memoryTax, 0))
+ .resourcesCalculator(memoryTax, 0)
.build();
tester.deployZoneApp();
@@ -214,7 +213,7 @@ public class DynamicDockerProvisionTest {
.flavors(flavors)
.hostProvisioner(new MockHostProvisioner(flavors, memoryTax))
.nameResolver(nameResolver)
- .resourcesCalculator(new MockResourcesCalculator(memoryTax, 0))
+ .resourcesCalculator(memoryTax, 0)
.build();
tester.deployZoneApp();
@@ -289,7 +288,7 @@ public class DynamicDockerProvisionTest {
.flavors(flavors)
.hostProvisioner(new MockHostProvisioner(flavors, memoryTax))
.nameResolver(nameResolver)
- .resourcesCalculator(new MockResourcesCalculator(memoryTax, 0))
+ .resourcesCalculator(memoryTax, 0)
.build();
tester.deployZoneApp();
@@ -324,7 +323,7 @@ public class DynamicDockerProvisionTest {
.flavors(flavors)
.hostProvisioner(new MockHostProvisioner(flavors, memoryTax))
.nameResolver(nameResolver)
- .resourcesCalculator(new MockResourcesCalculator(memoryTax, localDiskTax))
+ .resourcesCalculator(memoryTax, localDiskTax)
.build();
tester.deployZoneApp();
@@ -364,45 +363,6 @@ public class DynamicDockerProvisionTest {
}).when(hostProvisioner).provisionHosts(any(), any(), any(), any());
}
- private static class MockResourcesCalculator implements HostResourcesCalculator {
-
- private final int memoryTaxGb;
- private final int localDiskTax;
-
- public MockResourcesCalculator(int memoryTaxGb, int localDiskTax) {
- this.memoryTaxGb = memoryTaxGb;
- this.localDiskTax = localDiskTax;
- }
-
- @Override
- public NodeResources realResourcesOf(Node node, NodeRepository nodeRepository) {
- NodeResources resources = node.flavor().resources();
- if (node.type() == NodeType.host) return resources;
- return resources.withMemoryGb(resources.memoryGb() - memoryTaxGb)
- .withDiskGb(resources.diskGb() - ( resources.storageType() == local ? localDiskTax : 0));
- }
-
- @Override
- public NodeResources advertisedResourcesOf(Flavor flavor) {
- NodeResources resources = flavor.resources();
- if ( ! flavor.isConfigured()) return resources;
- return resources.withMemoryGb(resources.memoryGb() + memoryTaxGb);
- }
-
- @Override
- public NodeResources requestToReal(NodeResources resources) {
- return resources.withMemoryGb(resources.memoryGb() - memoryTaxGb)
- .withDiskGb(resources.diskGb() - ( resources.storageType() == local ? localDiskTax : 0) );
- }
-
- @Override
- public NodeResources realToRequest(NodeResources resources) {
- return resources.withMemoryGb(resources.memoryGb() + memoryTaxGb)
- .withDiskGb(resources.diskGb() + ( resources.storageType() == local ? localDiskTax : 0) );
- }
-
- }
-
private static class MockHostProvisioner implements HostProvisioner {
private final List<Flavor> hostFlavors;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
index b35f9dc88ae..7a7f8a7d891 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
@@ -413,7 +413,7 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east")))
.flavors(List.of(hostFlavor))
.build();
- tester.makeReadyHosts(30, hostFlavor.resources()).deployZoneApp();
+ tester.makeReadyHosts(4, hostFlavor.resources()).deployZoneApp();
ApplicationId app1 = tester.makeApplicationId("app1");
ClusterSpec cluster1 = ClusterSpec.request(ClusterSpec.Type.content, new ClusterSpec.Id("cluster1")).vespaVersion("7").build();
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
index 9a02bc17b4b..2427c0303c6 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java
@@ -56,6 +56,7 @@ import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collectors;
+import static com.yahoo.config.provision.NodeResources.StorageType.local;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -562,6 +563,11 @@ public class ProvisioningTester {
return this;
}
+ public Builder resourcesCalculator(int memoryTax, int diskTax) {
+ this.resourcesCalculator = new MockResourcesCalculator(memoryTax, diskTax);
+ return this;
+ }
+
public Builder zone(Zone zone) {
this.zone = zone;
return this;
@@ -640,4 +646,43 @@ public class ProvisioningTester {
@Override public void log(Level level, String message) { }
}
+ static class MockResourcesCalculator implements HostResourcesCalculator {
+
+ private final int memoryTaxGb;
+ private final int localDiskTax;
+
+ public MockResourcesCalculator(int memoryTaxGb, int localDiskTax) {
+ this.memoryTaxGb = memoryTaxGb;
+ this.localDiskTax = localDiskTax;
+ }
+
+ @Override
+ public NodeResources realResourcesOf(Node node, NodeRepository nodeRepository) {
+ NodeResources resources = node.flavor().resources();
+ if (node.type() == NodeType.host) return resources;
+ return resources.withMemoryGb(resources.memoryGb() - memoryTaxGb)
+ .withDiskGb(resources.diskGb() - ( resources.storageType() == local ? localDiskTax : 0));
+ }
+
+ @Override
+ public NodeResources advertisedResourcesOf(Flavor flavor) {
+ NodeResources resources = flavor.resources();
+ if ( ! flavor.isConfigured()) return resources;
+ return resources.withMemoryGb(resources.memoryGb() + memoryTaxGb);
+ }
+
+ @Override
+ public NodeResources requestToReal(NodeResources resources) {
+ return resources.withMemoryGb(resources.memoryGb() - memoryTaxGb)
+ .withDiskGb(resources.diskGb() - ( resources.storageType() == local ? localDiskTax : 0) );
+ }
+
+ @Override
+ public NodeResources realToRequest(NodeResources resources) {
+ return resources.withMemoryGb(resources.memoryGb() + memoryTaxGb)
+ .withDiskGb(resources.diskGb() + ( resources.storageType() == local ? localDiskTax : 0) );
+ }
+
+ }
+
}
diff --git a/searchcore/src/vespa/searchcore/grouping/groupingcontext.cpp b/searchcore/src/vespa/searchcore/grouping/groupingcontext.cpp
index 5c9321a6ff3..55e9ce16f70 100644
--- a/searchcore/src/vespa/searchcore/grouping/groupingcontext.cpp
+++ b/searchcore/src/vespa/searchcore/grouping/groupingcontext.cpp
@@ -20,7 +20,7 @@ GroupingContext::deserialize(const char *groupSpec, uint32_t groupSpecLen)
uint32_t numGroupings = 0;
nis >> numGroupings;
for (size_t i = 0; i < numGroupings; i++) {
- GroupingPtr grouping(new search::aggregation::Grouping);
+ auto grouping = std::make_shared<search::aggregation::Grouping>();
grouping->deserialize(nis);
grouping->setClock(&_clock);
grouping->setTimeOfDoom(_timeOfDoom);
diff --git a/searchcore/src/vespa/searchcore/grouping/groupingsession.cpp b/searchcore/src/vespa/searchcore/grouping/groupingsession.cpp
index 2c2a5ceacff..e336d5b25c9 100644
--- a/searchcore/src/vespa/searchcore/grouping/groupingsession.cpp
+++ b/searchcore/src/vespa/searchcore/grouping/groupingsession.cpp
@@ -41,7 +41,7 @@ GroupingSession::init(GroupingContext & groupingContext, const IAttributeContext
GroupingPtr g(sessionList[i]);
// Make internal copy of those we want to keep for another pass
if (!_sessionId.empty() && g->getLastLevel() < g->levels().size()) {
- GroupingPtr gp(new Grouping(*g));
+ auto gp = std::make_shared<Grouping>(*g);
gp->setLastLevel(gp->levels().size());
_groupingMap[gp->getId()] = gp;
g = gp;
@@ -62,7 +62,7 @@ GroupingSession::prepareThreadContextCreation(size_t num_threads)
GroupingContext::UP
GroupingSession::createThreadContext(size_t thread_id, const IAttributeContext &attrCtx)
{
- GroupingContext::UP ctx(new GroupingContext(*_mgrContext));
+ auto ctx = std::make_unique<GroupingContext>(*_mgrContext);
if (thread_id == 0) {
GroupingContext::GroupingList &groupingList = _mgrContext->getGroupingList();
for (size_t i = 0; i < groupingList.size(); ++i) {
diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp
index 4fcd5aff4f9..0869fc175a7 100644
--- a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp
+++ b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp
@@ -64,7 +64,7 @@ DocsumContext::initState()
DocsumReply::UP
DocsumContext::createReply()
{
- DocsumReply::UP reply(new DocsumReply());
+ auto reply = std::make_unique<DocsumReply>();
search::RawBuf buf(4096);
_docsumWriter.InitState(_attrMgr, &_docsumState);
reply->docsums.resize(_docsumState._docsumcnt);
diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/fieldcache.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/fieldcache.cpp
index ecc0569cccd..4c76361cf8e 100644
--- a/searchcore/src/vespa/searchcore/proton/docsummary/fieldcache.cpp
+++ b/searchcore/src/vespa/searchcore/proton/docsummary/fieldcache.cpp
@@ -27,7 +27,7 @@ FieldCache::FieldCache(const ResultClass &resClass,
const Field &field = docType.getField(fieldName);
LOG(debug, "Caching Field instance for field '%s': %s.%u",
fieldName.c_str(), field.getName().data(), field.getId());
- _cache.push_back(Field::CSP(new Field(field)));
+ _cache.push_back(std::make_shared<const Field>(field));
} else {
_cache.push_back(Field::CSP());
}
diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/fieldcacherepo.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/fieldcacherepo.cpp
index b97eba64f4c..25fe684b949 100644
--- a/searchcore/src/vespa/searchcore/proton/docsummary/fieldcacherepo.cpp
+++ b/searchcore/src/vespa/searchcore/proton/docsummary/fieldcacherepo.cpp
@@ -12,17 +12,17 @@ namespace proton {
FieldCacheRepo::FieldCacheRepo() :
_repo(),
- _defaultCache(new FieldCache())
+ _defaultCache(std::make_shared<const FieldCache>())
{
}
FieldCacheRepo::FieldCacheRepo(const ResultConfig &resConfig,
const DocumentType &docType) :
_repo(),
- _defaultCache(new FieldCache())
+ _defaultCache(std::make_shared<const FieldCache>())
{
for (ResultConfig::const_iterator it(resConfig.begin()), mt(resConfig.end()); it != mt; it++) {
- FieldCache::CSP cache(new FieldCache(*it, docType));
+ auto cache = std::make_shared<const FieldCache>(*it, docType);
vespalib::string className(it->GetClassName());
LOG(debug, "Adding field cache for summary class '%s' to repo",
className.c_str());
diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp b/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp
index 96f69179482..6016d60b880 100644
--- a/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp
+++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp
@@ -794,8 +794,7 @@ DocumentMetaStore::createWhiteListBlueprint() const
AttributeVector::SearchContext::UP
DocumentMetaStore::getSearch(std::unique_ptr<search::QueryTermSimple> qTerm, const SearchContextParams &) const
{
- return AttributeVector::SearchContext::UP
- (new documentmetastore::SearchContext(std::move(qTerm), *this));
+ return std::make_unique<documentmetastore::SearchContext>(std::move(qTerm), *this);
}
DocumentMetaStore::ConstIterator
@@ -1006,7 +1005,7 @@ void
DocumentMetaStore::holdUnblockShrinkLidSpace()
{
assert(_shrinkLidSpaceBlockers > 0);
- GenerationHeldBase::UP hold(new ShrinkBlockHeld(*this));
+ auto hold = std::make_unique<ShrinkBlockHeld>(*this);
getGenerationHolder().hold(std::move(hold));
incGeneration();
}
diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastorecontext.cpp b/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastorecontext.cpp
index b6486607821..959bdfa9baf 100644
--- a/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastorecontext.cpp
+++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastorecontext.cpp
@@ -15,7 +15,7 @@ DocumentMetaStoreContext::DocumentMetaStoreContext(BucketDBOwner::SP bucketDB,
const vespalib::string &name,
const search::GrowStrategy &grow,
const DocumentMetaStore::IGidCompare::SP &gidCompare) :
- _metaStoreAttr(new DocumentMetaStore(bucketDB, name, grow, gidCompare)),
+ _metaStoreAttr(std::make_shared<DocumentMetaStore>(bucketDB, name, grow, gidCompare)),
_metaStore(std::dynamic_pointer_cast<IDocumentMetaStore>(_metaStoreAttr))
{
}
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp
index 69f754cd594..26586da7784 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/pruneremoveddocumentsoperation.cpp
@@ -27,7 +27,7 @@ PruneRemovedDocumentsOperation(DocumentIdT docIdLimit, uint32_t subDbId)
: RemoveDocumentsOperation(FeedOperation::PRUNE_REMOVED_DOCUMENTS),
_subDbId(subDbId)
{
- LidVectorContext::SP lidsToRemove(new LidVectorContext(docIdLimit));
+ auto lidsToRemove = std::make_shared<LidVectorContext>(docIdLimit);
setLidsToRemove(lidsToRemove);
}
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp
index ef482a19ca3..14abade84b5 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/removedocumentsoperation.cpp
@@ -33,7 +33,7 @@ RemoveDocumentsOperation::deserializeLidsToRemove(vespalib::nbostream &is)
for (i = 0; i < mapSize; ++i) {
uint32_t subDbId;
is >> subDbId;
- LidVectorContext::SP lidsToRemove(new LidVectorContext());
+ auto lidsToRemove = std::make_shared<LidVectorContext>();
lidsToRemove->deserialize(is);
setLidsToRemove(subDbId, lidsToRemove);
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
index c8c5a3a427b..7149bf9ab7f 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
@@ -32,7 +32,7 @@ struct Mixer {
Blueprint::UP mix(Blueprint::UP indexes) {
if (attributes.get() == 0) {
if (indexes.get() == 0) {
- return Blueprint::UP(new EmptyBlueprint());
+ return std::make_unique<EmptyBlueprint>();
}
return Blueprint::UP(std::move(indexes));
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp b/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp
index 5758b9a796f..316cf92597e 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.cpp
@@ -7,8 +7,8 @@ namespace proton::matching {
FakeSearchContext::FakeSearchContext(size_t initialNumDocs)
: _clock(),
_doom(_clock, vespalib::steady_time()),
- _selector(new search::FixedSourceSelector(0, "fs", initialNumDocs)),
- _indexes(new IndexCollection(_selector)),
+ _selector(std::make_shared<search::FixedSourceSelector>(0, "fs", initialNumDocs)),
+ _indexes(std::make_shared<IndexCollection>(_selector)),
_attrSearchable(),
_docIdLimit(initialNumDocs)
{
diff --git a/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h b/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h
index 5a4ccc892b3..d23dd2ac551 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/fakesearchcontext.h
@@ -35,7 +35,7 @@ public:
~FakeSearchContext();
FakeSearchContext &addIdx(uint32_t id) {
- _indexes->append(id, IndexSearchable::SP(new FakeIndexSearchable()));
+ _indexes->append(id, std::make_shared<FakeIndexSearchable>());
return *this;
}
diff --git a/searchcore/src/vespa/searchcore/proton/metrics/documentdb_job_trackers.cpp b/searchcore/src/vespa/searchcore/proton/metrics/documentdb_job_trackers.cpp
index 8b3257ff47b..18475f06fc2 100644
--- a/searchcore/src/vespa/searchcore/proton/metrics/documentdb_job_trackers.cpp
+++ b/searchcore/src/vespa/searchcore/proton/metrics/documentdb_job_trackers.cpp
@@ -17,14 +17,14 @@ namespace proton {
DocumentDBJobTrackers::DocumentDBJobTrackers()
: _lock(),
_now(std::chrono::steady_clock::now()),
- _attributeFlush(new JobTracker(_now, _lock)),
- _memoryIndexFlush(new JobTracker(_now, _lock)),
- _diskIndexFusion(new JobTracker(_now, _lock)),
- _documentStoreFlush(new JobTracker(_now, _lock)),
- _documentStoreCompact(new JobTracker(_now, _lock)),
- _bucketMove(new JobTracker(_now, _lock)),
- _lidSpaceCompact(new JobTracker(_now, _lock)),
- _removedDocumentsPrune(new JobTracker(_now, _lock))
+ _attributeFlush(std::make_shared<JobTracker>(_now, _lock)),
+ _memoryIndexFlush(std::make_shared<JobTracker>(_now, _lock)),
+ _diskIndexFusion(std::make_shared<JobTracker>(_now, _lock)),
+ _documentStoreFlush(std::make_shared<JobTracker>(_now, _lock)),
+ _documentStoreCompact(std::make_shared<JobTracker>(_now, _lock)),
+ _bucketMove(std::make_shared<JobTracker>(_now, _lock)),
+ _lidSpaceCompact(std::make_shared<JobTracker>(_now, _lock)),
+ _removedDocumentsPrune(std::make_shared<JobTracker>(_now, _lock))
{
}
@@ -36,7 +36,7 @@ IFlushTarget::SP
trackFlushTarget(const IJobTracker::SP &tracker,
const IFlushTarget::SP &target)
{
- return IFlushTarget::SP(new JobTrackedFlushTarget(tracker, target));
+ return std::make_shared<JobTrackedFlushTarget>(tracker, target);
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/metrics/job_tracked_flush_target.cpp b/searchcore/src/vespa/searchcore/proton/metrics/job_tracked_flush_target.cpp
index 9eebe5010d2..14d76645fc7 100644
--- a/searchcore/src/vespa/searchcore/proton/metrics/job_tracked_flush_target.cpp
+++ b/searchcore/src/vespa/searchcore/proton/metrics/job_tracked_flush_target.cpp
@@ -25,7 +25,7 @@ JobTrackedFlushTarget::initFlush(SerialNum currentSerial)
FlushTask::UP targetTask = _target->initFlush(currentSerial);
_tracker->end();
if (targetTask.get() != nullptr) {
- return FlushTask::UP(new JobTrackedFlushTask(_tracker, std::move(targetTask)));
+ return std::make_unique<JobTrackedFlushTask>(_tracker, std::move(targetTask));
}
return FlushTask::UP();
}
diff --git a/searchcore/src/vespa/searchcore/proton/metrics/trans_log_server_metrics.cpp b/searchcore/src/vespa/searchcore/proton/metrics/trans_log_server_metrics.cpp
index a6e8ac54e86..85644c2111a 100644
--- a/searchcore/src/vespa/searchcore/proton/metrics/trans_log_server_metrics.cpp
+++ b/searchcore/src/vespa/searchcore/proton/metrics/trans_log_server_metrics.cpp
@@ -33,7 +33,7 @@ TransLogServerMetrics::considerAddDomains(const DomainStats &stats)
for (const auto &elem : stats) {
const vespalib::string &documentType = elem.first;
if (_domainMetrics.find(documentType) == _domainMetrics.end()) {
- _domainMetrics[documentType] = DomainMetrics::UP(new DomainMetrics(_parent, documentType));
+ _domainMetrics[documentType] = std::make_unique<DomainMetrics>(_parent, documentType);
}
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp b/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
index 9b1c66780cd..e939b07c26b 100644
--- a/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/reprocessing/attribute_reprocessing_initializer.cpp
@@ -101,9 +101,8 @@ getFieldsToPopulate(const ARIConfig &newCfg,
attrCfg.basicType().asString(),
toStr(populateField));
if (populateField) {
- fieldsToPopulate.push_back(IReprocessingRewriter::SP
- (new DocumentFieldPopulator(name,
- guard.getSP(), subDbName)));
+ fieldsToPopulate.push_back(std::make_shared<DocumentFieldPopulator>
+ (name, guard.getSP(), subDbName));
}
}
return fieldsToPopulate;
diff --git a/searchcore/src/vespa/searchcore/proton/server/attribute_writer_factory.h b/searchcore/src/vespa/searchcore/proton/server/attribute_writer_factory.h
index fe0820b9a39..3333041fb91 100644
--- a/searchcore/src/vespa/searchcore/proton/server/attribute_writer_factory.h
+++ b/searchcore/src/vespa/searchcore/proton/server/attribute_writer_factory.h
@@ -19,7 +19,7 @@ struct AttributeWriterFactory : public IAttributeWriterFactory
const AttributeWriter &oldAdapter = dynamic_cast<const AttributeWriter &>(*old.get());
const proton::IAttributeManager::SP &oldMgr = oldAdapter.getAttributeManager();
proton::IAttributeManager::SP newMgr = oldMgr->create(attrSpec);
- return IAttributeWriter::SP(new AttributeWriter(newMgr));
+ return std::make_shared<AttributeWriter>(newMgr);
}
};
diff --git a/searchcore/src/vespa/searchcore/proton/server/bootstrapconfigmanager.cpp b/searchcore/src/vespa/searchcore/proton/server/bootstrapconfigmanager.cpp
index edbf0c631a5..baf89a55ae3 100644
--- a/searchcore/src/vespa/searchcore/proton/server/bootstrapconfigmanager.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/bootstrapconfigmanager.cpp
@@ -78,7 +78,7 @@ BootstrapConfigManager::update(const ConfigSnapshot & snapshot)
if (snapshot.isChanged<ProtonConfig>(_configId, currentGen)) {
LOG(spam, "Proton config is changed");
std::unique_ptr<ProtonConfig> protonConfig = snapshot.getConfig<ProtonConfig>(_configId);
- TuneFileDocumentDB::SP tuneFileDocumentDB(new TuneFileDocumentDB);
+ auto tuneFileDocumentDB = std::make_shared<TuneFileDocumentDB>();
TuneFileDocumentDB &tune = *tuneFileDocumentDB;
ProtonConfig &conf = *protonConfig;
tune._index._indexing._write.setFromConfig<ProtonConfig::Indexing::Write>(conf.indexing.write.io);
diff --git a/searchcore/src/vespa/searchcore/proton/server/clusterstatehandler.cpp b/searchcore/src/vespa/searchcore/proton/server/clusterstatehandler.cpp
index fa0e0f33469..eb3c8ce6aa4 100644
--- a/searchcore/src/vespa/searchcore/proton/server/clusterstatehandler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/clusterstatehandler.cpp
@@ -64,7 +64,7 @@ ClusterStateHandler::performSetClusterState(const ClusterState *calc,
(calc->nodeInitializing() ? "true" : "false"),
_changedHandlers.size());
if (!_changedHandlers.empty()) {
- IBucketStateCalculator::SP newCalc(new ClusterStateAdapter(*calc));
+ auto newCalc = std::make_shared<ClusterStateAdapter>(*calc);
typedef std::vector<IClusterStateChangedHandler *> Chv;
Chv &chs(_changedHandlers);
for (Chv::const_iterator it = chs.begin(), ite = chs.end(); it != ite;
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
index d838013c0ef..a9a593b429d 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_blueprint_factory.cpp
@@ -141,7 +141,7 @@ public:
SearchIteratorUP createFilterSearch(bool strict, FilterConstraint constraint) const override {
(void) constraint; // We provide an iterator with exact results, so no need to take constraint into consideration.
- auto wrapper = std::make_unique<FilterWrapper>(getState());
+ auto wrapper = std::make_unique<FilterWrapper>(getState().numFields());
wrapper->wrap(createLeafSearch(wrapper->tfmda(), strict));
return wrapper;
}
diff --git a/searchlib/src/vespa/searchlib/diskindex/disktermblueprint.cpp b/searchlib/src/vespa/searchlib/diskindex/disktermblueprint.cpp
index 27aa070d514..09024505450 100644
--- a/searchlib/src/vespa/searchlib/diskindex/disktermblueprint.cpp
+++ b/searchlib/src/vespa/searchlib/diskindex/disktermblueprint.cpp
@@ -100,7 +100,7 @@ DiskTermBlueprint::createLeafSearch(const TermFieldMatchDataArray & tfmda, bool
SearchIterator::UP
DiskTermBlueprint::createFilterSearch(bool strict, FilterConstraint) const
{
- auto wrapper = std::make_unique<queryeval::FilterWrapper>(getState());
+ auto wrapper = std::make_unique<queryeval::FilterWrapper>(getState().numFields());
auto & tfmda = wrapper->tfmda();
if (_bitVector) {
wrapper->wrap(BitVectorIterator::create(_bitVector.get(), *tfmda[0], strict));
diff --git a/searchlib/src/vespa/searchlib/queryeval/filter_wrapper.h b/searchlib/src/vespa/searchlib/queryeval/filter_wrapper.h
index b67bacca118..27740df6ba6 100644
--- a/searchlib/src/vespa/searchlib/queryeval/filter_wrapper.h
+++ b/searchlib/src/vespa/searchlib/queryeval/filter_wrapper.h
@@ -3,7 +3,7 @@
#pragma once
#include "searchiterator.h"
-#include "blueprint.h"
+#include <vespa/searchlib/common/bitvector.h>
#include <vespa/searchlib/fef/termfieldmatchdata.h>
#include <vespa/searchlib/fef/termfieldmatchdataarray.h>
@@ -20,12 +20,12 @@ private:
fef::TermFieldMatchDataArray _tfmda;
std::unique_ptr<SearchIterator> _wrapped_search;
public:
- FilterWrapper(const Blueprint::State &state)
- : _unused_md(state.numFields()),
+ FilterWrapper(size_t num_fields)
+ : _unused_md(num_fields),
_tfmda(),
_wrapped_search()
{
- for (size_t i = 0; i < state.numFields(); ++i) {
+ for (size_t i = 0; i < num_fields; ++i) {
_tfmda.add(&_unused_md[i]);
}
}
diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java
index ccd2d80efb2..cf33b6033cd 100644
--- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java
+++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java
@@ -99,10 +99,7 @@ public class RestApi extends LoggingRequestHandler {
}
// For testing and development
- public RestApi(Executor executor,
- AccessLog accessLog,
- OperationHandler operationHandler,
- int threadsAvailable) {
+ RestApi(Executor executor, AccessLog accessLog, OperationHandler operationHandler, int threadsAvailable) {
super(executor, accessLog, null);
this.operationHandler = operationHandler;
this.threadsAvailableForApi = new AtomicInteger(threadsAvailable);
diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/FeedHandlerV3.java b/vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/FeedHandlerV3.java
index 05a64d633a4..03916949cae 100644
--- a/vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/FeedHandlerV3.java
+++ b/vespaclient-container-plugin/src/main/java/com/yahoo/vespa/http/server/FeedHandlerV3.java
@@ -45,9 +45,6 @@ public class FeedHandlerV3 extends LoggingRequestHandler {
protected final ReplyHandler feedReplyHandler;
private final Metric metric;
private final Object monitor = new Object();
- private int remainingThreadsForFeedingAllowance;
- private final Duration timeBetweenBumpingMaxThreads;
- private Instant nextTimeToAllocateAnotherThread = Instant.now();
private final AtomicInteger threadsAvailableForFeeding;
private static final Logger log = Logger.getLogger(FeedHandlerV3.class.getName());
@@ -65,20 +62,10 @@ public class FeedHandlerV3 extends LoggingRequestHandler {
this.metric = parentCtx.getMetric();
// 40% of the threads can be blocking on feeding before we deny requests.
if (threadpoolConfig != null) {
- remainingThreadsForFeedingAllowance = Math.max((int) (0.4 * threadpoolConfig.maxthreads()), 1);
- if (threadpoolConfig.softStartSeconds() > 0.0) {
- threadsAvailableForFeeding = new AtomicInteger(0);
- timeBetweenBumpingMaxThreads = Duration.ofMillis((long)(threadpoolConfig.softStartSeconds() * 1000) / remainingThreadsForFeedingAllowance);
- } else {
- threadsAvailableForFeeding = new AtomicInteger(remainingThreadsForFeedingAllowance);
- remainingThreadsForFeedingAllowance = 0;
- timeBetweenBumpingMaxThreads = null;
- }
+ threadsAvailableForFeeding = new AtomicInteger(Math.max((int) (0.4 * threadpoolConfig.maxthreads()), 1));
} else {
log.warning("No config for threadpool, using 200 for max blocking threads for feeding.");
threadsAvailableForFeeding = new AtomicInteger(200);
- remainingThreadsForFeedingAllowance = 0;
- timeBetweenBumpingMaxThreads = null;
}
}
@@ -93,12 +80,6 @@ public class FeedHandlerV3 extends LoggingRequestHandler {
String clientId = clientId(request);
ClientFeederV3 clientFeederV3;
synchronized (monitor) {
- Instant now = Instant.now();
- if ((remainingThreadsForFeedingAllowance > 0) && (now.isAfter(nextTimeToAllocateAnotherThread))) {
- threadsAvailableForFeeding.incrementAndGet();
- remainingThreadsForFeedingAllowance --;
- nextTimeToAllocateAnotherThread = now.plus(timeBetweenBumpingMaxThreads);
- }
if (! clientFeederByClientId.containsKey(clientId)) {
SourceSessionParams sourceSessionParams = sourceSessionParams(request);
clientFeederByClientId.put(clientId,
diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/feedhandler/v3/FeedTesterV3.java b/vespaclient-container-plugin/src/test/java/com/yahoo/feedhandler/v3/FeedTesterV3.java
index 0bb42851347..1efa8129cdb 100644
--- a/vespaclient-container-plugin/src/test/java/com/yahoo/feedhandler/v3/FeedTesterV3.java
+++ b/vespaclient-container-plugin/src/test/java/com/yahoo/feedhandler/v3/FeedTesterV3.java
@@ -77,20 +77,6 @@ public class FeedTesterV3 {
assertThat(Splitter.on("\n").splitToList(result).size(), is(101));
}
- @Test
- public void softRestart() throws Exception {
- ThreadpoolConfig.Builder builder = new ThreadpoolConfig.Builder().softStartSeconds(5);
- final FeedHandlerV3 feedHandlerV3 = setupFeederHandler(builder.build());
- for (int i= 0; i < 100; i++) {
- HttpResponse httpResponse = feedHandlerV3.handle(createRequest(100));
- ByteArrayOutputStream outStream = new ByteArrayOutputStream();
- httpResponse.render(outStream);
- assertThat(httpResponse.getContentType(), is("text/plain"));
- String result = Utf8.toString(outStream.toByteArray());
- assertThat(Splitter.on("\n").splitToList(result).size(), is(101));
- }
- }
-
private static DocumentTypeManager createDoctypeManager() {
DocumentTypeManager docTypeManager = new DocumentTypeManager();
DocumentType documentType = new DocumentType("testdocument");
diff --git a/zookeeper-server/zookeeper-server-3.5.8/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java b/zookeeper-server/zookeeper-server-3.5.8/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java
index 15d5d2f6f31..7f5b6170947 100644
--- a/zookeeper-server/zookeeper-server-3.5.8/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java
+++ b/zookeeper-server/zookeeper-server-3.5.8/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java
@@ -28,7 +28,7 @@ public class VespaZooKeeperServerImpl extends AbstractComponent implements Runna
this.zookeeperServerConfig = zookeeperServerConfig;
new Configurator(zookeeperServerConfig).writeConfigToDisk(TransportSecurityUtils.getOptions());
zkServerThread = new Thread(this, "zookeeper server");
- zkServerThread.start();
+ zkServerThread.start();
}
private void shutdown() {
diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
index 119509dd9cc..44ea8cece34 100644
--- a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
+++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/Configurator.java
@@ -12,9 +12,9 @@ import com.yahoo.security.X509CertificateUtils;
import com.yahoo.security.tls.TlsContext;
import com.yahoo.security.tls.TransportSecurityOptions;
import com.yahoo.text.Utf8;
+import com.yahoo.vespa.defaults.Defaults;
import javax.net.ssl.SSLContext;
-import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
@@ -26,29 +26,33 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
+import java.util.logging.Level;
import java.util.stream.Collectors;
import static com.yahoo.vespa.defaults.Defaults.getDefaults;
public class Configurator {
+
+ private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(Configurator.class.getName());
private static final String ZOOKEEPER_JMX_LOG4J_DISABLE = "zookeeper.jmx.log4j.disable";
static final String ZOOKEEPER_JUTE_MAX_BUFFER = "jute.maxbuffer";
private final ZookeeperServerConfig zookeeperServerConfig;
- private final String configFilePath;
- private final String jksKeyStoreFilePath;
+ private final Path configFilePath;
+ private final Path jksKeyStoreFilePath;
public Configurator(ZookeeperServerConfig zookeeperServerConfig) {
+ log.log(Level.FINE, zookeeperServerConfig.toString());
this.zookeeperServerConfig = zookeeperServerConfig;
- this.configFilePath = zookeeperServerConfig.zooKeeperConfigFile();
- this.jksKeyStoreFilePath = zookeeperServerConfig.jksKeyStoreFile();
+ this.configFilePath = makeAbsolutePath(zookeeperServerConfig.zooKeeperConfigFile());
+ this.jksKeyStoreFilePath = makeAbsolutePath(zookeeperServerConfig.jksKeyStoreFile());
System.setProperty(ZOOKEEPER_JMX_LOG4J_DISABLE, "true");
System.setProperty("zookeeper.snapshot.trust.empty", Boolean.valueOf(zookeeperServerConfig.trustEmptySnapshot()).toString());
System.setProperty(ZOOKEEPER_JUTE_MAX_BUFFER, Integer.valueOf(zookeeperServerConfig.juteMaxBuffer()).toString());
}
void writeConfigToDisk(Optional<TransportSecurityOptions> transportSecurityOptions) {
- new File(configFilePath).getParentFile().mkdirs();
+ configFilePath.toFile().getParentFile().mkdirs();
try {
writeZooKeeperConfigFile(zookeeperServerConfig, transportSecurityOptions);
@@ -61,7 +65,7 @@ public class Configurator {
private void writeZooKeeperConfigFile(ZookeeperServerConfig config,
Optional<TransportSecurityOptions> transportSecurityOptions) throws IOException {
- try (FileWriter writer = new FileWriter(configFilePath)) {
+ try (FileWriter writer = new FileWriter(configFilePath.toFile())) {
writer.write(transformConfigToString(config, transportSecurityOptions));
}
}
@@ -118,7 +122,7 @@ public class Configurator {
.withType(KeyStoreType.JKS)
.withKeyEntry("foo", privateKey, certificates);
- KeyStoreUtils.writeKeyStoreToFile(keyStoreBuilder.build(), Paths.get(jksKeyStoreFilePath));
+ KeyStoreUtils.writeKeyStoreToFile(keyStoreBuilder.build(), jksKeyStoreFilePath);
}
private void ensureThisServerIsRepresented(int myid, List<ZookeeperServerConfig.Server> servers) {
@@ -138,13 +142,18 @@ public class Configurator {
sb.append("server.").append(server.id()).append("=").append(server.hostname()).append(":").append(server.quorumPort()).append(":").append(server.electionPort()).append("\n");
}
-
-
-
static Set<String> zookeeperServerHostnames(ZookeeperServerConfig zookeeperServerConfig) {
return zookeeperServerConfig.server().stream().map(ZookeeperServerConfig.Server::hostname).collect(Collectors.toSet());
}
+ Path makeAbsolutePath(String filename) {
+ Path path = Paths.get(filename);
+ if (path.isAbsolute())
+ return path;
+ else
+ return Paths.get(Defaults.getDefaults().underVespaHome(filename));
+ }
+
private interface TlsConfig {
default Set<String> allowedCiphers(SSLContext sslContext) { return new TreeSet<>(TlsContext.getAllowedCipherSuites(sslContext)); }
@@ -162,7 +171,7 @@ public class Configurator {
String configFieldPrefix();
- String jksKeyStoreFilePath();
+ Path jksKeyStoreFilePath();
SSLContext sslContext();
@@ -195,9 +204,9 @@ public class Configurator {
static class TlsClientServerConfig implements TlsConfig {
private final SSLContext sslContext;
- private final String jksKeyStoreFilePath;
+ private final Path jksKeyStoreFilePath;
- TlsClientServerConfig(SSLContext sslContext, String jksKeyStoreFilePath) {
+ TlsClientServerConfig(SSLContext sslContext, Path jksKeyStoreFilePath) {
this.sslContext = sslContext;
this.jksKeyStoreFilePath = jksKeyStoreFilePath;
}
@@ -233,7 +242,7 @@ public class Configurator {
}
@Override
- public String jksKeyStoreFilePath() {
+ public Path jksKeyStoreFilePath() {
return jksKeyStoreFilePath;
}
@@ -246,9 +255,9 @@ public class Configurator {
static class TlsQuorumConfig implements TlsConfig {
private final SSLContext sslContext;
- private final String jksKeyStoreFilePath;
+ private final Path jksKeyStoreFilePath;
- TlsQuorumConfig(SSLContext sslContext, String jksKeyStoreFilePath) {
+ TlsQuorumConfig(SSLContext sslContext, Path jksKeyStoreFilePath) {
this.sslContext = sslContext;
this.jksKeyStoreFilePath = jksKeyStoreFilePath;
}
@@ -293,7 +302,7 @@ public class Configurator {
}
@Override
- public String jksKeyStoreFilePath() {
+ public Path jksKeyStoreFilePath() {
return jksKeyStoreFilePath;
}