summaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4InvokerFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4InvokerFactory.java')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4InvokerFactory.java52
1 files changed, 40 insertions, 12 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4InvokerFactory.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4InvokerFactory.java
index f68bb718c8d..51048db3cb7 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4InvokerFactory.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4InvokerFactory.java
@@ -8,10 +8,12 @@ import com.yahoo.search.Result;
import com.yahoo.search.dispatch.FillInvoker;
import com.yahoo.search.dispatch.InterleavedFillInvoker;
import com.yahoo.search.dispatch.InterleavedSearchInvoker;
-import com.yahoo.search.dispatch.SearchCluster;
import com.yahoo.search.dispatch.SearchInvoker;
+import com.yahoo.search.dispatch.searchcluster.Node;
+import com.yahoo.search.dispatch.searchcluster.SearchCluster;
import com.yahoo.search.result.Hit;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -30,18 +32,20 @@ import java.util.Set;
public class FS4InvokerFactory {
private final FS4ResourcePool fs4ResourcePool;
private final VespaBackEndSearcher searcher;
- private final ImmutableMap<Integer, SearchCluster.Node> nodesByKey;
+ private final SearchCluster searchCluster;
+ private final ImmutableMap<Integer, Node> nodesByKey;
public FS4InvokerFactory(FS4ResourcePool fs4ResourcePool, SearchCluster searchCluster, VespaBackEndSearcher searcher) {
this.fs4ResourcePool = fs4ResourcePool;
this.searcher = searcher;
+ this.searchCluster = searchCluster;
- ImmutableMap.Builder<Integer, SearchCluster.Node> builder = ImmutableMap.builder();
+ ImmutableMap.Builder<Integer, Node> builder = ImmutableMap.builder();
searchCluster.groups().values().forEach(group -> group.nodes().forEach(node -> builder.put(node.key(), node)));
this.nodesByKey = builder.build();
}
- public SearchInvoker getSearchInvoker(Query query, SearchCluster.Node node) {
+ public SearchInvoker getSearchInvoker(Query query, Node node) {
Backend backend = fs4ResourcePool.getBackend(node.hostname(), node.fs4port());
return new FS4SearchInvoker(searcher, query, backend.openChannel(), node);
}
@@ -49,22 +53,46 @@ public class FS4InvokerFactory {
/**
* Create a {@link SearchInvoker} for a list of content nodes.
*
- * @param query the search query being processed
- * @param nodes pre-selected list of content nodes
- * @return Optional containing the SearchInvoker or <i>empty</i> if some node in the list is invalid
+ * @param query
+ * the search query being processed
+ * @param groupId
+ * the id of the node group to which the nodes belong
+ * @param nodes
+ * pre-selected list of content nodes
+ * @param acceptIncompleteCoverage
+ * if some of the nodes are unavailable and this parameter is
+ * <b>false</b>, verify that the remaining set of nodes has enough
+ * coverage
+ * @return Optional containing the SearchInvoker or <i>empty</i> if some node in the
+ * list is invalid and the remaining coverage is not sufficient
*/
- public Optional<SearchInvoker> getSearchInvoker(Query query, List<SearchCluster.Node> nodes) {
+ public Optional<SearchInvoker> getSearchInvoker(Query query, int groupId, List<Node> nodes, boolean acceptIncompleteCoverage) {
Map<Integer, SearchInvoker> invokers = new HashMap<>();
- for (SearchCluster.Node node : nodes) {
+ Set<Integer> failed = null;
+ for (Node node : nodes) {
if (node.isWorking()) {
Backend backend = fs4ResourcePool.getBackend(node.hostname(), node.fs4port());
if (backend.probeConnection()) {
invokers.put(node.key(), new FS4SearchInvoker(searcher, query, backend.openChannel(), node));
} else {
- return Optional.empty();
+ if(failed == null) {
+ failed = new HashSet<>();
+ }
+ failed.add(node.key());
}
}
}
+ if (failed != null && ! acceptIncompleteCoverage) {
+ List<Node> success = new ArrayList<>(nodes.size() - failed.size());
+ for (Node node : nodes) {
+ if (!failed.contains(node.key())) {
+ success.add(node);
+ }
+ }
+ if (!searchCluster.isPartialGroupCoverageSufficient(groupId, success)) {
+ return Optional.empty();
+ }
+ }
if (invokers.size() == 1) {
return Optional.of(invokers.values().iterator().next());
} else {
@@ -72,7 +100,7 @@ public class FS4InvokerFactory {
}
}
- public FillInvoker getFillInvoker(Query query, SearchCluster.Node node) {
+ public FillInvoker getFillInvoker(Query query, Node node) {
return new FS4FillInvoker(searcher, query, fs4ResourcePool, node.hostname(), node.fs4port(), node.key());
}
@@ -88,7 +116,7 @@ public class FS4InvokerFactory {
Query query = result.getQuery();
Map<Integer, FillInvoker> invokers = new HashMap<>();
for (Integer distKey : requiredNodes) {
- SearchCluster.Node node = nodesByKey.get(distKey);
+ Node node = nodesByKey.get(distKey);
if (node == null) {
return Optional.empty();
}