diff --git a/core/src/main/java/org/elasticsearch/search/SearchService.java b/core/src/main/java/org/elasticsearch/search/SearchService.java index 9666df8cc56..477aac2b014 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchService.java +++ b/core/src/main/java/org/elasticsearch/search/SearchService.java @@ -25,8 +25,8 @@ import org.apache.lucene.search.TopDocs; import org.apache.lucene.util.IOUtils; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ExceptionsHelper; -import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.action.search.SearchTask; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Nullable; @@ -85,7 +85,6 @@ import org.elasticsearch.search.sort.SortAndFormats; import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.suggest.Suggest; import org.elasticsearch.search.suggest.completion.CompletionSuggestion; -import org.elasticsearch.tasks.Task; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool.Cancellable; import org.elasticsearch.threadpool.ThreadPool.Names; @@ -722,7 +721,9 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv if (source.profile()) { context.setProfilers(new Profilers(context.searcher())); } - context.timeout(source.timeout()); + if (source.timeout() != null) { + context.timeout(source.timeout()); + } context.terminateAfter(source.terminateAfter()); if (source.aggregations() != null) { try { diff --git a/core/src/test/java/org/elasticsearch/search/SearchServiceTests.java b/core/src/test/java/org/elasticsearch/search/SearchServiceTests.java index 717d64a53e7..2db44c9d0ba 100644 --- a/core/src/test/java/org/elasticsearch/search/SearchServiceTests.java +++ b/core/src/test/java/org/elasticsearch/search/SearchServiceTests.java @@ -31,6 +31,8 @@ import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.index.IndexService; import org.elasticsearch.index.query.AbstractQueryBuilder; @@ -44,6 +46,7 @@ import org.elasticsearch.plugins.SearchPlugin; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.ShardFetchRequest; import org.elasticsearch.search.internal.AliasFilter; +import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.internal.ShardSearchLocalRequest; import org.elasticsearch.search.query.QuerySearchResultProvider; import org.elasticsearch.test.ESSingleNodeTestCase; @@ -59,6 +62,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import static java.util.Collections.singletonList; import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; @@ -74,6 +78,11 @@ public class SearchServiceTests extends ESSingleNodeTestCase { return pluginList(FailOnRewriteQueryPlugin.class); } + @Override + protected Settings nodeSettings() { + return Settings.builder().put("search.default_search_timeout", "5s").build(); + } + public void testClearOnClose() throws ExecutionException, InterruptedException { createIndex("index"); client().prepareIndex("index", "type", "1").setSource("field", "value").setRefreshPolicy(IMMEDIATE).get(); @@ -197,6 +206,40 @@ public class SearchServiceTests extends ESSingleNodeTestCase { } } + public void testTimeout() throws IOException { + createIndex("index"); + final SearchService service = getInstanceFromNode(SearchService.class); + final IndicesService indicesService = getInstanceFromNode(IndicesService.class); + final IndexService indexService = indicesService.indexServiceSafe(resolveIndex("index")); + final IndexShard indexShard = indexService.getShard(0); + final SearchContext contextWithDefaultTimeout = service.createContext( + new ShardSearchLocalRequest( + indexShard.shardId(), + 1, + SearchType.DEFAULT, + new SearchSourceBuilder(), + new String[0], + false, + new AliasFilter(null, Strings.EMPTY_ARRAY)), + null); + // the search context should inherit the default timeout + assertThat(contextWithDefaultTimeout.timeout(), equalTo(TimeValue.timeValueSeconds(5))); + + final long seconds = randomIntBetween(6, 10); + final SearchContext context = service.createContext( + new ShardSearchLocalRequest( + indexShard.shardId(), + 1, + SearchType.DEFAULT, + new SearchSourceBuilder().timeout(TimeValue.timeValueSeconds(seconds)), + new String[0], + false, + new AliasFilter(null, Strings.EMPTY_ARRAY)), + null); + // the search context should inherit the query timeout + assertThat(context.timeout(), equalTo(TimeValue.timeValueSeconds(seconds))); + } + public static class FailOnRewriteQueryPlugin extends Plugin implements SearchPlugin { @Override public List> getQueries() {