diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2020-12-03 14:03:25 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2020-12-03 17:11:36 +0100 |
commit | fb21ab2649cd20e2361926404e1843c47c15d4fd (patch) | |
tree | f0bea441c78b8bd0390471fe8c57434df8effd89 | |
parent | 5832d0d6182f69bcd67403cb219420ddbe29487c (diff) |
Move non-permanent feature flags to ModelContext.FeatureFlags
14 files changed, 160 insertions, 116 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 09bc6c77e82..8fafa7e6048 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 @@ -49,8 +49,35 @@ public interface ModelContext { /** The Vespa version we want nodes to become */ Version wantedNodeVespaVersion(); + /** + * How to remove temporary feature flags: + * 1) + * - Remove flag definition from Flags + * - Remove method implementation from ModelContextImpl.FeatureFlags + * - Modify default implementation of below method to return the new default value + * - Remove all usage of below method from config-model + * + * 2) + * - Wait for all config-model versions in hosted production to include above changes + * - Remove below method + */ interface FeatureFlags { @ModelFeatureFlag(owners = {"bjorncs", "jonmv"}) default boolean enableAutomaticReindexing() { return false; } + @ModelFeatureFlag(owners = {"baldersheim"}, comment = "Revisit in May or June 2020") default double defaultTermwiseLimit() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"vekterli"}) default boolean useThreePhaseUpdates() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"geirst"}, comment = "Remove on 7.XXX when this is default on") default boolean useDirectStorageApiRpc() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"geirst"}, comment = "Remove on 7.XXX when this is default on") default boolean useFastValueTensorImplementation() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"baldersheim"}, comment = "Select sequencer type use while feeding") default String feedSequencerType() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"baldersheim"}) default String responseSequencerType() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"baldersheim"}) default int defaultNumResponseThreads() { return 2; } + @ModelFeatureFlag(owners = {"baldersheim"}) default boolean skipCommunicationManagerThread() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"baldersheim"}) default boolean skipMbusRequestThread() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"baldersheim"}) default boolean skipMbusReplyThread() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"tokle"}) default boolean useAccessControlTlsHandshakeClientAuth() { return false; } + @ModelFeatureFlag(owners = {"baldersheim"}) default boolean useAsyncMessageHandlingOnSchedule() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"baldersheim"}) default int contentNodeBucketDBStripeBits() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"baldersheim"}) default int mergeChunkSize() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"baldersheim"}) default double feedConcurrency() { throw new UnsupportedOperationException("TODO specify default value"); } } /** Warning: As elsewhere in this package, do not make backwards incompatible changes that will break old config models! */ @@ -68,39 +95,8 @@ public interface ModelContext { boolean isBootstrap(); boolean isFirstTimeDeployment(); - // TODO: Only needed for LbServicesProducerTest - default boolean useDedicatedNodeForLogserver() { return true; } - default Optional<EndpointCertificateSecrets> endpointCertificateSecrets() { return Optional.empty(); } - // TODO Revisit in May or June 2020 - double defaultTermwiseLimit(); - - default int defaultNumResponseThreads() { return 2; } - - /// Default setting for the gc-options attribute if not specified explicit by application - String jvmGCOptions(); - - // Select sequencer type use while feeding. - String feedSequencerType(); - String responseSequencerType(); - boolean skipCommunicationManagerThread(); - boolean skipMbusRequestThread(); - boolean skipMbusReplyThread(); - - boolean useAsyncMessageHandlingOnSchedule(); - int contentNodeBucketDBStripeBits(); - int mergeChunkSize(); - double feedConcurrency(); - - boolean useThreePhaseUpdates(); - - // TODO Remove on 7.XXX when this is default on. - boolean useDirectStorageApiRpc(); - - // TODO Remove on 7.XXX when this is default on. - boolean useFastValueTensorImplementation(); - default Optional<AthenzDomain> athenzDomain() { return Optional.empty(); } Optional<ApplicationRoles> applicationRoles(); @@ -109,9 +105,27 @@ public interface ModelContext { return Quota.unlimited(); } - // TODO(mortent): Temporary feature flag - default boolean useAccessControlTlsHandshakeClientAuth() { return false; } + /// Default setting for the gc-options attribute if not specified explicit by application + String jvmGCOptions(); + // TODO(somebody): Only needed for LbServicesProducerTest + default boolean useDedicatedNodeForLogserver() { return true; } + // NOTE: Use FeatureFlags interface above instead of non-permament flags + @Deprecated double defaultTermwiseLimit(); + @Deprecated default int defaultNumResponseThreads() { return 2; } + @Deprecated String feedSequencerType(); + @Deprecated String responseSequencerType(); + @Deprecated boolean skipCommunicationManagerThread(); + @Deprecated boolean skipMbusRequestThread(); + @Deprecated boolean skipMbusReplyThread(); + @Deprecated boolean useAsyncMessageHandlingOnSchedule(); + @Deprecated int contentNodeBucketDBStripeBits(); + @Deprecated int mergeChunkSize(); + @Deprecated double feedConcurrency(); + @Deprecated boolean useThreePhaseUpdates(); + @Deprecated boolean useDirectStorageApiRpc(); + @Deprecated boolean useFastValueTensorImplementation(); + @Deprecated default boolean useAccessControlTlsHandshakeClientAuth() { return false; } } @Retention(RetentionPolicy.RUNTIME) 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 0e4d0db484e..02bc0c9ca84 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 @@ -26,6 +26,7 @@ import java.util.Set; * * @author hakonhall */ +@SuppressWarnings("deprecation") public class TestProperties implements ModelContext.Properties, ModelContext.FeatureFlags { private boolean multitenant = false; diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java index 56a5d539906..c656a426b61 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java @@ -191,7 +191,7 @@ public class RawRankProfile implements RankProfilesConfig.Producer { numThreadsPerSearch = rankProfile.getNumThreadsPerSearch(); minHitsPerThread = rankProfile.getMinHitsPerThread(); numSearchPartitions = rankProfile.getNumSearchPartitions(); - termwiseLimit = rankProfile.getTermwiseLimit().orElse(deployProperties.defaultTermwiseLimit()); + termwiseLimit = rankProfile.getTermwiseLimit().orElse(deployProperties.featureFlags().defaultTermwiseLimit()); keepRankCount = rankProfile.getKeepRankCount(); rankScoreDropLimit = rankProfile.getRankScoreDropLimit(); ignoreDefaultRankFeatures = rankProfile.getIgnoreDefaultRankFeatures(); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 78f37275c30..7e6c6486b86 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -377,7 +377,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { } EndpointCertificateSecrets endpointCertificateSecrets = deployState.endpointCertificateSecrets().get(); - boolean enforceHandshakeClientAuth = context.properties().useAccessControlTlsHandshakeClientAuth() && + boolean enforceHandshakeClientAuth = context.properties().featureFlags().useAccessControlTlsHandshakeClientAuth() && cluster.getHttp().getAccessControl() .map(accessControl -> accessControl.clientAuthentication) .map(clientAuth -> clientAuth.equals(AccessControl.ClientAuthentication.need)) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java index 34b6dd017cf..736424e263d 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentNode.java @@ -29,14 +29,14 @@ public abstract class ContentNode extends AbstractService private final boolean skipMbusReplyThread; private final boolean useDirectStorageApiRpc; - public ContentNode(ModelContext.Properties properties, AbstractConfigProducer parent, String clusterName, String rootDirectory, int distributionKey) { + public ContentNode(ModelContext.FeatureFlags featureFlags, AbstractConfigProducer<?> parent, String clusterName, String rootDirectory, int distributionKey) { super(parent, "" + distributionKey); this.distributionKey = distributionKey; - this.skipCommunicationManagerThread = properties.skipCommunicationManagerThread(); - this.skipMbusRequestThread = properties.skipMbusRequestThread(); - this.skipMbusReplyThread = properties.skipMbusReplyThread(); + this.skipCommunicationManagerThread = featureFlags.skipCommunicationManagerThread(); + this.skipMbusRequestThread = featureFlags.skipMbusRequestThread(); + this.skipMbusReplyThread = featureFlags.skipMbusReplyThread(); this.rootDirectory = rootDirectory; - this.useDirectStorageApiRpc = properties.useDirectStorageApiRpc(); + this.useDirectStorageApiRpc = featureFlags.useDirectStorageApiRpc(); initialize(); setProp("clustertype", "content"); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java index 948093f6c77..bc1d138b6d5 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java @@ -95,7 +95,7 @@ public class ContentSearchCluster extends AbstractConfigProducer implements Prot ContentSearchCluster search = new ContentSearchCluster(ancestor, clusterName, - deployState.getProperties(), + deployState.getProperties().featureFlags(), documentDefinitions, globallyDistributedDocuments, getFlushOnShutdown(flushOnShutdownElem, deployState), @@ -191,7 +191,7 @@ public class ContentSearchCluster extends AbstractConfigProducer implements Prot private ContentSearchCluster(AbstractConfigProducer parent, String clusterName, - ModelContext.Properties featureFlags, + ModelContext.FeatureFlags featureFlags, Map<String, NewDocumentType> documentDefinitions, Set<NewDocumentType> globallyDistributedDocuments, boolean flushOnShutdown, diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/Distributor.java b/config-model/src/main/java/com/yahoo/vespa/model/content/Distributor.java index f03b7144e38..ec677911da6 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/Distributor.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/Distributor.java @@ -35,7 +35,7 @@ public class Distributor extends ContentNode { } Distributor(ModelContext.Properties properties, DistributorCluster parent, int distributionKey, Integer distributorBasePort, PersistenceEngine provider) { - super(properties, parent, parent.getClusterName(), + super(properties.featureFlags(), parent, parent.getClusterName(), StorageNode.rootFolder + parent.getClusterName() + "/distributor/" + distributionKey, distributionKey); this.provider = provider; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/DistributorCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/DistributorCluster.java index 25e3efcb78f..d7140ee0a71 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/DistributorCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/DistributorCluster.java @@ -102,7 +102,7 @@ public class DistributorCluster extends AbstractConfigProducer<Distributor> impl final ModelElement documentsNode = clusterElement.child("documents"); final GcOptions gc = parseGcOptions(documentsNode); final boolean hasIndexedDocumentType = clusterContainsIndexedDocumentType(documentsNode); - boolean useThreePhaseUpdates = deployState.getProperties().useThreePhaseUpdates(); + boolean useThreePhaseUpdates = deployState.getProperties().featureFlags().useThreePhaseUpdates(); return new DistributorCluster(parent, new BucketSplitting.Builder().build(new ModelElement(producerSpec)), gc, 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 d47d77897e8..afe285faf19 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 @@ -3,12 +3,11 @@ package com.yahoo.vespa.model.content; import com.yahoo.config.model.api.ModelContext; import com.yahoo.config.model.deploy.DeployState; -import com.yahoo.config.provision.Flavor; +import com.yahoo.config.model.producer.AbstractConfigProducer; import com.yahoo.vespa.config.content.StorFilestorConfig; import com.yahoo.vespa.config.content.core.StorBucketmoverConfig; import com.yahoo.vespa.config.content.core.StorCommunicationmanagerConfig; import com.yahoo.vespa.config.content.core.StorServerConfig; -import com.yahoo.config.model.producer.AbstractConfigProducer; import com.yahoo.vespa.defaults.Defaults; import com.yahoo.vespa.model.application.validation.RestartConfigs; import com.yahoo.vespa.model.builder.xml.dom.ModelElement; @@ -39,7 +38,7 @@ public class StorageNode extends ContentNode implements StorServerConfig.Produce } StorageNode(ModelContext.Properties properties, StorageCluster cluster, Double capacity, int distributionKey, boolean retired) { - super(properties, cluster, cluster.getClusterName(), + super(properties.featureFlags(), cluster, cluster.getClusterName(), rootFolder + cluster.getClusterName() + "/storage/" + distributionKey, distributionKey); this.retired = retired; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/FileStorProducer.java b/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/FileStorProducer.java index fd4de13be39..ab5dab4fbb9 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/FileStorProducer.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/FileStorProducer.java @@ -13,7 +13,7 @@ public class FileStorProducer implements StorFilestorConfig.Producer { public static class Builder { protected FileStorProducer build(ModelContext.Properties properties, ContentCluster parent, ModelElement clusterElem) { - return new FileStorProducer(properties, parent, getThreads(clusterElem)); + return new FileStorProducer(properties.featureFlags(), parent, getThreads(clusterElem)); } private Integer getThreads(ModelElement clusterElem) { @@ -60,13 +60,13 @@ public class FileStorProducer implements StorFilestorConfig.Producer { final int twoMB = 0x200000; return ((value + twoMB - 1)/twoMB) * twoMB; } - public FileStorProducer(ModelContext.Properties properties, ContentCluster parent, Integer numThreads) { + public FileStorProducer(ModelContext.FeatureFlags featureFlags, ContentCluster parent, Integer numThreads) { this.numThreads = numThreads; this.cluster = parent; - this.reponseNumThreads = properties.defaultNumResponseThreads(); - this.responseSequencerType = convertResponseSequencerType(properties.responseSequencerType()); - useAsyncMessageHandlingOnSchedule = properties.useAsyncMessageHandlingOnSchedule(); - mergeChunkSize = alignUp2MiB(properties.mergeChunkSize()); // Align up to default huge page size. + this.reponseNumThreads = featureFlags.defaultNumResponseThreads(); + this.responseSequencerType = convertResponseSequencerType(featureFlags.responseSequencerType()); + useAsyncMessageHandlingOnSchedule = featureFlags.useAsyncMessageHandlingOnSchedule(); + mergeChunkSize = alignUp2MiB(featureFlags.mergeChunkSize()); // Align up to default huge page size. } @Override diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorServerProducer.java b/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorServerProducer.java index dc9a7cda32c..e34ccb9696c 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorServerProducer.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/storagecluster/StorServerProducer.java @@ -15,7 +15,7 @@ public class StorServerProducer implements StorServerConfig.Producer { ModelElement tuning = element.child("tuning"); StorServerProducer producer = new StorServerProducer(ContentCluster.getClusterId(element)); - producer.setBucketDBStripeBits(properties.contentNodeBucketDBStripeBits()); + producer.setBucketDBStripeBits(properties.featureFlags().contentNodeBucketDBStripeBits()); if (tuning == null) return producer; ModelElement merges = tuning.child("merges"); 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 c8cf9407a31..9d3505e932f 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 @@ -2,7 +2,6 @@ package com.yahoo.vespa.model.search; import com.yahoo.cloud.config.filedistribution.FiledistributorrpcConfig; -import com.yahoo.config.model.api.Model; import com.yahoo.config.model.api.ModelContext; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.producer.AbstractConfigProducer; @@ -15,7 +14,6 @@ import com.yahoo.vespa.config.content.core.StorCommunicationmanagerConfig; import com.yahoo.vespa.config.content.core.StorServerConfig; import com.yahoo.vespa.config.content.core.StorStatusConfig; import com.yahoo.vespa.config.search.core.ProtonConfig; -import static com.yahoo.vespa.defaults.Defaults.getDefaults; import com.yahoo.vespa.model.AbstractService; import com.yahoo.vespa.model.PortAllocBridge; import com.yahoo.vespa.model.admin.monitoring.Monitoring; @@ -30,6 +28,8 @@ import org.w3c.dom.Element; import java.util.HashMap; import java.util.Optional; +import static com.yahoo.vespa.defaults.Defaults.getDefaults; + /** * Represents a search node (proton). * <p> @@ -142,7 +142,7 @@ public class SearchNode extends AbstractService implements // Properties are set in DomSearchBuilder this.tuning = tuning; this.resourceLimits = resourceLimits; - this.useFastValueTensorImplementation = props.useFastValueTensorImplementation(); + this.useFastValueTensorImplementation = props.featureFlags().useFastValueTensorImplementation(); } private void setPropertiesElastic(String clusterName, int distributionKey) { 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 eda962af5ac..9f3ae86b2cf 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 @@ -149,12 +149,57 @@ public class ModelContextImpl implements ModelContext { public static class FeatureFlags implements ModelContext.FeatureFlags { private final boolean enableAutomaticReindexing; + private final double defaultTermwiseLimit; + private final boolean useThreePhaseUpdates; + private final boolean useDirectStorageApiRpc; + private final boolean useFastValueTensorImplementation; + private final String feedSequencer; + private final String responseSequencer; + private final int numResponseThreads; + private final boolean skipCommunicationManagerThread; + private final boolean skipMbusRequestThread; + private final boolean skipMbusReplyThread; + private final boolean useAccessControlTlsHandshakeClientAuth; + private final boolean useAsyncMessageHandlingOnSchedule; + private final int contentNodeBucketDBStripeBits; + private final int mergeChunkSize; + private final double feedConcurrency; public FeatureFlags(FlagSource source, ApplicationId appId) { this.enableAutomaticReindexing = flagValue(source, appId, Flags.ENABLE_AUTOMATIC_REINDEXING); + defaultTermwiseLimit = flagValue(source, appId, Flags.DEFAULT_TERM_WISE_LIMIT); + useThreePhaseUpdates = flagValue(source, appId, Flags.USE_THREE_PHASE_UPDATES); + useDirectStorageApiRpc = flagValue(source, appId, Flags.USE_DIRECT_STORAGE_API_RPC); + useFastValueTensorImplementation = flagValue(source, appId, Flags.USE_FAST_VALUE_TENSOR_IMPLEMENTATION); + feedSequencer = flagValue(source, appId, Flags.FEED_SEQUENCER_TYPE); + responseSequencer = flagValue(source, appId, Flags.RESPONSE_SEQUENCER_TYPE); + numResponseThreads = flagValue(source, appId, Flags.RESPONSE_NUM_THREADS); + skipCommunicationManagerThread = flagValue(source, appId, Flags.SKIP_COMMUNICATIONMANAGER_THREAD); + skipMbusRequestThread = flagValue(source, appId, Flags.SKIP_MBUS_REQUEST_THREAD); + skipMbusReplyThread = flagValue(source, appId, Flags.SKIP_MBUS_REPLY_THREAD); + this.useAccessControlTlsHandshakeClientAuth = flagValue(source, appId, Flags.USE_ACCESS_CONTROL_CLIENT_AUTHENTICATION); + useAsyncMessageHandlingOnSchedule = flagValue(source, appId, Flags.USE_ASYNC_MESSAGE_HANDLING_ON_SCHEDULE); + contentNodeBucketDBStripeBits = flagValue(source, appId, Flags.CONTENT_NODE_BUCKET_DB_STRIPE_BITS); + mergeChunkSize = flagValue(source, appId, Flags.MERGE_CHUNK_SIZE); + feedConcurrency = flagValue(source, appId, Flags.FEED_CONCURRENCY); } @Override public boolean enableAutomaticReindexing() { return enableAutomaticReindexing; } + @Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; } + @Override public boolean useThreePhaseUpdates() { return useThreePhaseUpdates; } + @Override public boolean useDirectStorageApiRpc() { return useDirectStorageApiRpc; } + @Override public boolean useFastValueTensorImplementation() { return useFastValueTensorImplementation; } + @Override public String feedSequencerType() { return feedSequencer; } + @Override public String responseSequencerType() { return responseSequencer; } + @Override public int defaultNumResponseThreads() { return numResponseThreads; } + @Override public boolean skipCommunicationManagerThread() { return skipCommunicationManagerThread; } + @Override public boolean skipMbusRequestThread() { return skipMbusRequestThread; } + @Override public boolean skipMbusReplyThread() { return skipMbusReplyThread; } + @Override public boolean useAccessControlTlsHandshakeClientAuth() { return useAccessControlTlsHandshakeClientAuth; } + @Override public boolean useAsyncMessageHandlingOnSchedule() { return useAsyncMessageHandlingOnSchedule; } + @Override public int contentNodeBucketDBStripeBits() { return contentNodeBucketDBStripeBits; } + @Override public int mergeChunkSize() { return mergeChunkSize; } + @Override public double feedConcurrency() { return feedConcurrency; } private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) { return flag.bindTo(source) @@ -164,6 +209,7 @@ public class ModelContextImpl implements ModelContext { } + @SuppressWarnings("deprecation") // for old feature flag methods in ModelContext.Properties public static class Properties implements ModelContext.Properties { private final ModelContext.FeatureFlags featureFlags; @@ -178,21 +224,24 @@ public class ModelContextImpl implements ModelContext { private final Set<ContainerEndpoint> endpoints; private final boolean isBootstrap; private final boolean isFirstTimeDeployment; + private final Optional<EndpointCertificateSecrets> endpointCertificateSecrets; + private final Optional<AthenzDomain> athenzDomain; + private final Optional<ApplicationRoles> applicationRoles; + private final Quota quota; + + private final String jvmGCOPtions; + + // Old non-permanent feature flags. Use ModelContext.FeatureFlag instead + private final double defaultTermwiseLimit; private final boolean useThreePhaseUpdates; private final boolean useDirectStorageApiRpc; private final boolean useFastValueTensorImplementation; - private final Optional<EndpointCertificateSecrets> endpointCertificateSecrets; - private final double defaultTermwiseLimit; - private final String jvmGCOPtions; private final String feedSequencer; private final String responseSequencer; private final int numResponseThreads; private final boolean skipCommunicationManagerThread; private final boolean skipMbusRequestThread; private final boolean skipMbusReplyThread; - private final Optional<AthenzDomain> athenzDomain; - private final Optional<ApplicationRoles> applicationRoles; - private final Quota quota; private final boolean useAccessControlTlsHandshakeClientAuth; private final boolean useAsyncMessageHandlingOnSchedule; private final int contentNodeBucketDBStripeBits; @@ -223,43 +272,28 @@ public class ModelContextImpl implements ModelContext { this.isBootstrap = isBootstrap; this.isFirstTimeDeployment = isFirstTimeDeployment; this.endpointCertificateSecrets = endpointCertificateSecrets; - defaultTermwiseLimit = Flags.DEFAULT_TERM_WISE_LIMIT.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - useThreePhaseUpdates = Flags.USE_THREE_PHASE_UPDATES.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - useDirectStorageApiRpc = Flags.USE_DIRECT_STORAGE_API_RPC.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - useFastValueTensorImplementation = Flags.USE_FAST_VALUE_TENSOR_IMPLEMENTATION.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - jvmGCOPtions = PermanentFlags.JVM_GC_OPTIONS.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - feedSequencer = Flags.FEED_SEQUENCER_TYPE.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - responseSequencer = Flags.RESPONSE_SEQUENCER_TYPE.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - numResponseThreads = Flags.RESPONSE_NUM_THREADS.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - skipCommunicationManagerThread = Flags.SKIP_COMMUNICATIONMANAGER_THREAD.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - skipMbusRequestThread = Flags.SKIP_MBUS_REQUEST_THREAD.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - skipMbusReplyThread = Flags.SKIP_MBUS_REPLY_THREAD.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); this.athenzDomain = athenzDomain; this.applicationRoles = applicationRoles; this.quota = maybeQuota.orElseGet(Quota::unlimited); - this.useAccessControlTlsHandshakeClientAuth = - Flags.USE_ACCESS_CONTROL_CLIENT_AUTHENTICATION.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()) - .value(); - useAsyncMessageHandlingOnSchedule = Flags.USE_ASYNC_MESSAGE_HANDLING_ON_SCHEDULE.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - contentNodeBucketDBStripeBits = Flags.CONTENT_NODE_BUCKET_DB_STRIPE_BITS.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - mergeChunkSize = Flags.MERGE_CHUNK_SIZE.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); - feedConcurrency = Flags.FEED_CONCURRENCY.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); + + jvmGCOPtions = flagValue(flagSource, applicationId, PermanentFlags.JVM_GC_OPTIONS); + + // Old non-permanent feature flags. Use ModelContext.FeatureFlag instead + defaultTermwiseLimit = flagValue(flagSource, applicationId, Flags.DEFAULT_TERM_WISE_LIMIT); + useThreePhaseUpdates = flagValue(flagSource, applicationId, Flags.USE_THREE_PHASE_UPDATES); + useDirectStorageApiRpc = flagValue(flagSource, applicationId, Flags.USE_DIRECT_STORAGE_API_RPC); + useFastValueTensorImplementation = flagValue(flagSource, applicationId, Flags.USE_FAST_VALUE_TENSOR_IMPLEMENTATION); + feedSequencer = flagValue(flagSource, applicationId, Flags.FEED_SEQUENCER_TYPE); + responseSequencer = flagValue(flagSource, applicationId, Flags.RESPONSE_SEQUENCER_TYPE); + numResponseThreads = flagValue(flagSource, applicationId, Flags.RESPONSE_NUM_THREADS); + skipCommunicationManagerThread = flagValue(flagSource, applicationId, Flags.SKIP_COMMUNICATIONMANAGER_THREAD); + skipMbusRequestThread = flagValue(flagSource, applicationId, Flags.SKIP_MBUS_REQUEST_THREAD); + skipMbusReplyThread = flagValue(flagSource, applicationId, Flags.SKIP_MBUS_REPLY_THREAD); + this.useAccessControlTlsHandshakeClientAuth = flagValue(flagSource, applicationId, Flags.USE_ACCESS_CONTROL_CLIENT_AUTHENTICATION); + useAsyncMessageHandlingOnSchedule = flagValue(flagSource, applicationId, Flags.USE_ASYNC_MESSAGE_HANDLING_ON_SCHEDULE); + contentNodeBucketDBStripeBits = flagValue(flagSource, applicationId, Flags.CONTENT_NODE_BUCKET_DB_STRIPE_BITS); + mergeChunkSize = flagValue(flagSource, applicationId, Flags.MERGE_CHUNK_SIZE); + feedConcurrency = flagValue(flagSource, applicationId, Flags.FEED_CONCURRENCY); } @Override public ModelContext.FeatureFlags featureFlags() { return featureFlags; } @@ -305,24 +339,6 @@ public class ModelContextImpl implements ModelContext { public Optional<EndpointCertificateSecrets> endpointCertificateSecrets() { return endpointCertificateSecrets; } @Override - public double defaultTermwiseLimit() { return defaultTermwiseLimit; } - - @Override - public boolean useThreePhaseUpdates() { - return useThreePhaseUpdates; - } - - @Override - public boolean useDirectStorageApiRpc() { - return useDirectStorageApiRpc; - } - - @Override - public boolean useFastValueTensorImplementation() { - return useFastValueTensorImplementation; - } - - @Override public Optional<AthenzDomain> athenzDomain() { return athenzDomain; } @Override @@ -330,19 +346,32 @@ public class ModelContextImpl implements ModelContext { return applicationRoles; } + @Override public Quota quota() { return quota; } + @Override public String jvmGCOptions() { return jvmGCOPtions; } + + // Old non-permanent feature flags. Use ModelContext.FeatureFlag instead + @Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; } + @Override public boolean useThreePhaseUpdates() { return useThreePhaseUpdates; } + @Override public boolean useDirectStorageApiRpc() { return useDirectStorageApiRpc; } + @Override public boolean useFastValueTensorImplementation() { return useFastValueTensorImplementation; } @Override public String feedSequencerType() { return feedSequencer; } @Override public String responseSequencerType() { return responseSequencer; } @Override public int defaultNumResponseThreads() { return numResponseThreads; } @Override public boolean skipCommunicationManagerThread() { return skipCommunicationManagerThread; } @Override public boolean skipMbusRequestThread() { return skipMbusRequestThread; } @Override public boolean skipMbusReplyThread() { return skipMbusReplyThread; } - @Override public Quota quota() { return quota; } @Override public boolean useAccessControlTlsHandshakeClientAuth() { return useAccessControlTlsHandshakeClientAuth; } @Override public boolean useAsyncMessageHandlingOnSchedule() { return useAsyncMessageHandlingOnSchedule; } @Override public int contentNodeBucketDBStripeBits() { return contentNodeBucketDBStripeBits; } @Override public int mergeChunkSize() { return mergeChunkSize; } @Override public double feedConcurrency() { return feedConcurrency; } + + private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) { + return flag.bindTo(source) + .with(FetchVector.Dimension.APPLICATION_ID, appId.serializedForm()) + .boxedValue(); + } } } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java index 6694ac8c694..47150f0d5a0 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java @@ -31,6 +31,7 @@ import static org.junit.Assert.assertTrue; /** * @author Ulf Lilleengen */ +@SuppressWarnings("deprecation") public class ModelContextImplTest { @Test |