diff options
author | Jon Bratseth <bratseth@verizonmedia.com> | 2019-06-09 12:15:43 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@verizonmedia.com> | 2019-06-09 12:15:43 +0200 |
commit | 20513f2cb1f9c65406c32dd717e738d394fc1d1b (patch) | |
tree | 8801ffcd7fb2f7f31f66f2ce4db99c6752b909ef /container-search/src/main/java/com/yahoo | |
parent | 79cd883d5df45dc236e5cebf2c21b5487c791df6 (diff) |
Extract execution creation into ExecutionFactory
Diffstat (limited to 'container-search/src/main/java/com/yahoo')
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(); + } + +} |