summaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@verizonmedia.com>2019-06-09 12:15:43 +0200
committerJon Bratseth <bratseth@verizonmedia.com>2019-06-09 12:15:43 +0200
commit20513f2cb1f9c65406c32dd717e738d394fc1d1b (patch)
tree8801ffcd7fb2f7f31f66f2ce4db99c6752b909ef /container-search/src/main/java/com/yahoo
parent79cd883d5df45dc236e5cebf2c21b5487c791df6 (diff)
Extract execution creation into ExecutionFactory
Diffstat (limited to 'container-search/src/main/java/com/yahoo')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/IndexFacts.java5
-rw-r--r--container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java96
-rw-r--r--container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java79
3 files changed, 123 insertions, 57 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java b/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java
index 2fcd2466dd8..1fd8cce9889 100644
--- a/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java
+++ b/container-search/src/main/java/com/yahoo/prelude/IndexFacts.java
@@ -253,11 +253,14 @@ public class IndexFacts {
/**
* Freeze this to prevent further changes.
+ *
+ * @return this for chaining
*/
- public void freeze() {
+ public IndexFacts freeze() {
hasNGramIndices = hasNGramIndices();
// TODO: Freeze content!
frozen = true;
+ return this;
}
/** Whether this contains any index which has isNGram()==true. This is free to ask on a frozen instance. */
diff --git a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
index cb69f2abd07..8e654bf34b8 100644
--- a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
+++ b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
@@ -6,9 +6,6 @@ import com.yahoo.collections.Tuple2;
import com.yahoo.component.ComponentSpecification;
import com.yahoo.component.Vtag;
import com.yahoo.component.chain.Chain;
-import com.yahoo.component.chain.ChainsConfigurer;
-import com.yahoo.component.chain.model.ChainsModel;
-import com.yahoo.component.chain.model.ChainsModelBuilder;
import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.container.QrSearchersConfig;
import com.yahoo.container.core.ChainsConfig;
@@ -24,14 +21,12 @@ import com.yahoo.language.Linguistics;
import com.yahoo.log.LogLevel;
import com.yahoo.net.HostName;
import com.yahoo.net.UriTools;
-import com.yahoo.prelude.IndexFacts;
-import com.yahoo.prelude.IndexModel;
import com.yahoo.prelude.query.QueryException;
import com.yahoo.prelude.query.parser.ParseException;
-import com.yahoo.prelude.query.parser.SpecialTokenRegistry;
import com.yahoo.processing.rendering.Renderer;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.query.ranking.SoftTimeout;
+import com.yahoo.search.searchchain.ExecutionFactory;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.ObjectTraverser;
import com.yahoo.vespa.config.SlimeUtils;
@@ -46,7 +41,6 @@ import com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry;
import com.yahoo.search.query.profile.config.QueryProfileConfigurer;
import com.yahoo.search.query.profile.config.QueryProfilesConfig;
import com.yahoo.search.query.properties.DefaultProperties;
-import com.yahoo.search.rendering.RendererRegistry;
import com.yahoo.search.result.ErrorMessage;
import com.yahoo.search.searchchain.Execution;
import com.yahoo.search.searchchain.SearchChainRegistry;
@@ -93,19 +87,9 @@ public class SearchHandler extends LoggingRequestHandler {
private Value searchConnections;
- private final SearchChainRegistry searchChainRegistry;
-
- private final RendererRegistry rendererRegistry;
-
- private final IndexFacts indexFacts;
-
- private final SpecialTokenRegistry specialTokens;
-
public static final String defaultSearchChainName = "default";
private static final String fallbackSearchChain = "vespa";
- private final Linguistics linguistics;
-
private final CompiledQueryProfileRegistry queryProfileRegistry;
/** If present, responses from this will set the HTTP response header with this key to the host name of this */
@@ -113,6 +97,8 @@ public class SearchHandler extends LoggingRequestHandler {
private final String selfHostname = HostName.getLocalhost();
+ private final ExecutionFactory executionFactory;
+
private final class MeanConnections implements Callback {
@Override
@@ -127,31 +113,19 @@ public class SearchHandler extends LoggingRequestHandler {
}
@Inject
- public SearchHandler(ChainsConfig chainsConfig,
- IndexInfoConfig indexInfo,
- QrSearchersConfig clusters,
- SpecialtokensConfig specialtokens,
- Statistics statistics,
- Linguistics linguistics,
+ public SearchHandler(Statistics statistics,
Metric metric,
- ComponentRegistry<Renderer> renderers,
Executor executor,
AccessLog accessLog,
QueryProfilesConfig queryProfileConfig,
- ComponentRegistry<Searcher> searchers,
- ContainerHttpConfig containerHttpConfig) {
+ ContainerHttpConfig containerHttpConfig,
+ ExecutionFactory executionFactory) {
super(executor, accessLog, metric, true);
log.log(LogLevel.DEBUG, "SearchHandler.init " + System.identityHashCode(this));
- searchChainRegistry = new SearchChainRegistry(searchers);
- setupSearchChainRegistry(searchers, chainsConfig);
- indexFacts = new IndexFacts(new IndexModel(indexInfo, clusters));
- indexFacts.freeze();
- specialTokens = new SpecialTokenRegistry(specialtokens);
- rendererRegistry = new RendererRegistry(renderers.allComponents());
QueryProfileRegistry queryProfileRegistry = QueryProfileConfigurer.createFromConfig(queryProfileConfig);
this.queryProfileRegistry = queryProfileRegistry.compile();
+ this.executionFactory = executionFactory;
- this.linguistics = linguistics;
this.maxThreads = examineExecutor(executor);
searchConnections = new Value(SEARCH_CONNECTIONS, statistics,
@@ -164,16 +138,28 @@ public class SearchHandler extends LoggingRequestHandler {
Optional.empty() : Optional.of( containerHttpConfig.hostResponseHeaderKey());
}
- @Override
- protected void destroy() {
- super.destroy();
- rendererRegistry.deconstruct();
- }
-
- private void setupSearchChainRegistry(ComponentRegistry<Searcher> searchers, ChainsConfig chainsConfig) {
- ChainsModel chainsModel = ChainsModelBuilder.buildFromConfig(chainsConfig);
- ChainsConfigurer.prepareChainRegistry(searchChainRegistry, chainsModel, searchers);
- searchChainRegistry.freeze();
+ /** @deprecated use the other constructor */
+ @Deprecated // TODO: Remove on Vespa 8
+ public SearchHandler(ChainsConfig chainsConfig,
+ IndexInfoConfig indexInfo,
+ QrSearchersConfig clusters,
+ SpecialtokensConfig specialtokens,
+ Statistics statistics,
+ Linguistics linguistics,
+ Metric metric,
+ ComponentRegistry<Renderer> renderers,
+ Executor executor,
+ AccessLog accessLog,
+ QueryProfilesConfig queryProfileConfig,
+ ComponentRegistry<Searcher> searchers,
+ ContainerHttpConfig containerHttpConfig) {
+ this(statistics,
+ metric,
+ executor,
+ accessLog,
+ queryProfileConfig,
+ containerHttpConfig,
+ new ExecutionFactory(chainsConfig, indexInfo, clusters, searchers, specialtokens, linguistics, renderers));
}
private static int examineExecutor(Executor executor) {
@@ -278,7 +264,7 @@ public class SearchHandler extends LoggingRequestHandler {
ErrorMessage.createInvalidQueryParameter("No search chain named '" + searchChainName + "' was found"));
} else {
String pathAndQuery = UriTools.rawRequest(request.getUri());
- result = search(pathAndQuery, query, searchChain, searchChainRegistry);
+ result = search(pathAndQuery, query, searchChain);
}
// Transform result to response
@@ -301,7 +287,7 @@ public class SearchHandler extends LoggingRequestHandler {
@NonNull
private Renderer<Result> toRendererCopy(ComponentSpecification format) {
- Renderer<Result> renderer = rendererRegistry.getRenderer(format);
+ Renderer<Result> renderer = executionFactory.rendererRegistry().getRenderer(format);
renderer = perRenderingCopy(renderer);
return renderer;
}
@@ -312,28 +298,27 @@ public class SearchHandler extends LoggingRequestHandler {
chainName = defaultSearchChainName;
}
- Chain<Searcher> searchChain = searchChainRegistry.getChain(chainName);
+ Chain<Searcher> searchChain = executionFactory.searchChainRegistry().getChain(chainName);
if (searchChain == null && explicitChainName == null) { // explicit chain not found should cause error
chainName = fallbackSearchChain;
- searchChain = searchChainRegistry.getChain(chainName);
+ searchChain = executionFactory.searchChainRegistry().getChain(chainName);
}
return new Tuple2<>(chainName, searchChain);
}
/** Used from container SDK, for internal use only */
- public Result searchAndFill(Query query, Chain<? extends Searcher> searchChain, SearchChainRegistry registry) {
+ public Result searchAndFill(Query query, Chain<? extends Searcher> searchChain) {
Result errorResult = validateQuery(query);
if (errorResult != null) return errorResult;
- Renderer<Result> renderer = rendererRegistry.getRenderer(query.getPresentation().getRenderer());
+ Renderer<Result> renderer = executionFactory.rendererRegistry().getRenderer(query.getPresentation().getRenderer());
// docsumClass null means "unset", so we set it (it might be null
// here too in which case it will still be "unset" after we set it :-)
if (query.getPresentation().getSummary() == null && renderer instanceof com.yahoo.search.rendering.Renderer)
query.getPresentation().setSummary(((com.yahoo.search.rendering.Renderer) renderer).getDefaultSummaryClass());
- Execution execution = new Execution(searchChain,
- new Execution.Context(registry, indexFacts, specialTokens, rendererRegistry, linguistics));
+ Execution execution = executionFactory.newExecution(searchChain);
query.getModel().setExecution(execution);
execution.trace().setForceTimestamps(query.properties().getBoolean(FORCE_TIMESTAMPS, false));
if (query.properties().getBoolean(DETAILED_TIMING_LOGGING, false)) {
@@ -362,7 +347,7 @@ public class SearchHandler extends LoggingRequestHandler {
* For internal use only
*/
public Renderer<Result> getRendererCopy(ComponentSpecification spec) {
- Renderer<Result> renderer = rendererRegistry.getRenderer(spec);
+ Renderer<Result> renderer = executionFactory.rendererRegistry().getRenderer(spec);
return perRenderingCopy(renderer);
}
@@ -380,7 +365,7 @@ public class SearchHandler extends LoggingRequestHandler {
}
}
- private Result search(String request, Query query, Chain<Searcher> searchChain, SearchChainRegistry registry) {
+ private Result search(String request, Query query, Chain<Searcher> searchChain) {
if (query.getTraceLevel() >= 2) {
query.trace("Invoking " + searchChain, false, 2);
}
@@ -393,7 +378,7 @@ public class SearchHandler extends LoggingRequestHandler {
new IllegalStateException("searchConnections reference is null."));
}
try {
- return searchAndFill(query, searchChain, registry);
+ return searchAndFill(query, searchChain);
} catch (ParseException e) {
ErrorMessage error = ErrorMessage.createIllegalQuery("Could not parse query [" + request + "]: "
+ Exceptions.toMessageString(e));
@@ -502,8 +487,7 @@ public class SearchHandler extends LoggingRequestHandler {
query.trace("Vespa version: " + Vtag.currentVersion.toString(), false, 4);
}
- public SearchChainRegistry getSearchChainRegistry() {
- return searchChainRegistry;
+ public SearchChainRegistry getSearchChainRegistry() { return executionFactory.searchChainRegistry();
}
static private String getMediaType(HttpRequest request) {
diff --git a/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java b/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java
new file mode 100644
index 00000000000..470e74bb974
--- /dev/null
+++ b/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java
@@ -0,0 +1,79 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.searchchain;
+
+import com.yahoo.component.AbstractComponent;
+import com.yahoo.component.chain.Chain;
+import com.yahoo.component.chain.ChainsConfigurer;
+import com.yahoo.component.chain.model.ChainsModel;
+import com.yahoo.component.chain.model.ChainsModelBuilder;
+import com.yahoo.component.provider.ComponentRegistry;
+import com.yahoo.container.QrSearchersConfig;
+import com.yahoo.container.core.ChainsConfig;
+import com.yahoo.language.Linguistics;
+import com.yahoo.prelude.IndexFacts;
+import com.yahoo.prelude.IndexModel;
+import com.yahoo.prelude.query.parser.SpecialTokenRegistry;
+import com.yahoo.processing.rendering.Renderer;
+import com.yahoo.search.Searcher;
+import com.yahoo.search.config.IndexInfoConfig;
+import com.yahoo.search.rendering.RendererRegistry;
+import com.yahoo.vespa.configdefinition.SpecialtokensConfig;
+
+/**
+ * Provides creation of fully configured query Execution instances.
+ * Have an instance of this injected if you need to execute queries which are not initiated from
+ * an external request.
+ *
+ * @author bratseth
+ */
+public class ExecutionFactory extends AbstractComponent {
+
+ private final SearchChainRegistry searchChainRegistry;
+ private final IndexFacts indexFacts;
+ private final SpecialTokenRegistry specialTokens;
+ private final Linguistics linguistics;
+ private final RendererRegistry rendererRegistry;
+
+ public ExecutionFactory(ChainsConfig chainsConfig,
+ IndexInfoConfig indexInfo,
+ QrSearchersConfig clusters,
+ ComponentRegistry<Searcher> searchers,
+ SpecialtokensConfig specialTokens,
+ Linguistics linguistics,
+ ComponentRegistry<Renderer> renderers) {
+ this.searchChainRegistry = createSearchChainRegistry(searchers, chainsConfig);
+ this.indexFacts = new IndexFacts(new IndexModel(indexInfo, clusters)).freeze();
+ this.specialTokens = new SpecialTokenRegistry(specialTokens);
+ this.linguistics = linguistics;
+ this.rendererRegistry = new RendererRegistry(renderers.allComponents());
+ }
+
+ private SearchChainRegistry createSearchChainRegistry(ComponentRegistry<Searcher> searchers, ChainsConfig chainsConfig) {
+ SearchChainRegistry searchChainRegistry = new SearchChainRegistry(searchers);
+ ChainsModel chainsModel = ChainsModelBuilder.buildFromConfig(chainsConfig);
+ ChainsConfigurer.prepareChainRegistry(searchChainRegistry, chainsModel, searchers);
+ searchChainRegistry.freeze();
+ return searchChainRegistry;
+ }
+
+ /**
+ * Creates a new execution starting at a search chain.
+ * An execution instance should be used once to execute a (tree of) search chains.
+ */
+ public Execution newExecution(Chain<? extends Searcher> searchChain) {
+ return new Execution(searchChain,
+ new Execution.Context(searchChainRegistry, indexFacts, specialTokens, rendererRegistry, linguistics));
+ }
+
+ /** Returns the search chain registry used by this */
+ public SearchChainRegistry searchChainRegistry() { return searchChainRegistry; }
+
+ /** Returns the renderers known to this */
+ public RendererRegistry rendererRegistry() { return rendererRegistry; }
+
+ @Override
+ public void deconstruct() {
+ rendererRegistry.deconstruct();
+ }
+
+}