summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorOlli Virtanen <olli.virtanen@oath.com>2019-03-04 13:42:16 +0100
committerOlli Virtanen <olli.virtanen@oath.com>2019-03-04 13:42:16 +0100
commit1ca887bd458e5ae92182a7902f9d1aedb6cc40e2 (patch)
treef9b8b5acc7869c0d75bc443b26d005891fb31bca /container-search
parentac76b7090b26a82d5cdbc801a05196685b059f0c (diff)
Propagate errors quicker
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java11
-rw-r--r--container-search/src/test/java/com/yahoo/prelude/fastsearch/FS4SearchInvokerTestCase.java71
2 files changed, 79 insertions, 3 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java
index ae0a29aa80b..856de8d33ef 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/FS4SearchInvoker.java
@@ -61,15 +61,20 @@ public class FS4SearchInvoker extends SearchInvoker implements ResponseMonitor<F
try {
boolean couldSend = channel.sendPacket(queryPacket);
if (!couldSend) {
- pendingSearchError = ErrorMessage.createBackendCommunicationError("Could not reach '" + getName() + "'");
+ setPendingError("Could not reach '" + getName() + "'");
}
} catch (InvalidChannelException e) {
- pendingSearchError = ErrorMessage.createBackendCommunicationError("Invalid channel " + getName());
+ setPendingError("Invalid channel " + getName());
} catch (IllegalStateException e) {
- pendingSearchError = ErrorMessage.createBackendCommunicationError("Illegal state in FS4: " + e.getMessage());
+ setPendingError("Illegal state in FS4: " + e.getMessage());
}
}
+ private void setPendingError(String message) {
+ pendingSearchError = ErrorMessage.createBackendCommunicationError(message);
+ responseAvailable();
+ }
+
@Override
protected Result getSearchResult(CacheKey cacheKey, Execution execution) throws IOException {
if (pendingSearchError != null) {
diff --git a/container-search/src/test/java/com/yahoo/prelude/fastsearch/FS4SearchInvokerTestCase.java b/container-search/src/test/java/com/yahoo/prelude/fastsearch/FS4SearchInvokerTestCase.java
new file mode 100644
index 00000000000..4a78d4e7631
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/prelude/fastsearch/FS4SearchInvokerTestCase.java
@@ -0,0 +1,71 @@
+package com.yahoo.prelude.fastsearch;
+
+import com.yahoo.fs4.BasicPacket;
+import com.yahoo.fs4.QueryPacket;
+import com.yahoo.fs4.mplex.FS4Channel;
+import com.yahoo.fs4.mplex.InvalidChannelException;
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.dispatch.InterleavedSearchInvoker;
+import com.yahoo.search.dispatch.MockSearchCluster;
+import com.yahoo.search.dispatch.ResponseMonitor;
+import com.yahoo.search.searchchain.Execution;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Optional;
+
+import static org.junit.Assert.assertThat;
+
+public class FS4SearchInvokerTestCase {
+ @SuppressWarnings("resource")
+ @Test
+ public void testThatConnectionErrorsAreReportedImmediately() throws IOException {
+ var query = new Query("?");
+ query.setTimeout(1000);
+
+ var searcher = mockSearcher();
+ var cluster = new MockSearchCluster("?", 1, 1);
+ var fs4invoker = new FS4SearchInvoker(searcher, query, mockFailingChannel(), Optional.empty());
+ var interleave = new InterleavedSearchInvoker(Collections.singleton(fs4invoker), searcher, cluster);
+
+ long start = System.currentTimeMillis();
+ interleave.search(query, QueryPacket.create(null, null), null, null);
+ long elapsed = System.currentTimeMillis() - start;
+
+ assertThat("Connection error should fail fast", elapsed, Matchers.lessThan(500L));
+ }
+
+ private static VespaBackEndSearcher mockSearcher() {
+ return new VespaBackEndSearcher() {
+ @Override
+ protected Result doSearch2(Query query, QueryPacket queryPacket, CacheKey cacheKey, Execution execution) {
+ return null;
+ }
+
+ @Override
+ protected void doPartialFill(Result result, String summaryClass) {}
+ };
+ }
+
+ private static FS4Channel mockFailingChannel() {
+ return new FS4Channel() {
+ @Override
+ public boolean sendPacket(BasicPacket packet) throws InvalidChannelException, IOException {
+ // pretend there's a connection error
+ return false;
+ }
+
+ @Override
+ public void setQuery(Query q) {}
+
+ @Override
+ public void setResponseMonitor(ResponseMonitor<FS4Channel> monitor) {}
+
+ @Override
+ public void close() {}
+ };
+ }
+}