Respect default search timeout

The default search timeout is not respected because the timeout is
unconditionally set from the query. This commit fixes this issue, and
adds a test that the default search timeout is correctly attached to the
search context.

Relates #21599
This commit is contained in:
Jason Tedor 2016-11-16 12:43:47 -05:00 committed by GitHub
parent d06a8903fd
commit 9792b5792a
2 changed files with 47 additions and 3 deletions

View File

@ -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 {

View File

@ -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<QuerySpec<?>> getQueries() {