Introducing took time for _msearch
This commit adds the took time to the response for _msearch. Relates #23767
This commit is contained in:
parent
59657ad1cb
commit
b9896465cd
|
@ -21,12 +21,14 @@ package org.elasticsearch.action.search;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.ExceptionsHelper;
|
import org.elasticsearch.ExceptionsHelper;
|
||||||
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Streamable;
|
import org.elasticsearch.common.io.stream.Streamable;
|
||||||
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
|
||||||
|
@ -112,11 +114,14 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
||||||
|
|
||||||
private Item[] items;
|
private Item[] items;
|
||||||
|
|
||||||
|
private long tookInMillis;
|
||||||
|
|
||||||
MultiSearchResponse() {
|
MultiSearchResponse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MultiSearchResponse(Item[] items) {
|
public MultiSearchResponse(Item[] items, long tookInMillis) {
|
||||||
this.items = items;
|
this.items = items;
|
||||||
|
this.tookInMillis = tookInMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -131,6 +136,13 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
||||||
return this.items;
|
return this.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long the msearch took.
|
||||||
|
*/
|
||||||
|
public TimeValue getTook() {
|
||||||
|
return new TimeValue(tookInMillis);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
|
@ -138,6 +150,9 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
||||||
for (int i = 0; i < items.length; i++) {
|
for (int i = 0; i < items.length; i++) {
|
||||||
items[i] = Item.readItem(in);
|
items[i] = Item.readItem(in);
|
||||||
}
|
}
|
||||||
|
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
tookInMillis = in.readVLong();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -147,11 +162,15 @@ public class MultiSearchResponse extends ActionResponse implements Iterable<Mult
|
||||||
for (Item item : items) {
|
for (Item item : items) {
|
||||||
item.writeTo(out);
|
item.writeTo(out);
|
||||||
}
|
}
|
||||||
|
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
out.writeVLong(tookInMillis);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
|
builder.field("took", tookInMillis);
|
||||||
builder.startArray(Fields.RESPONSES);
|
builder.startArray(Fields.RESPONSES);
|
||||||
for (Item item : items) {
|
for (Item item : items) {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
|
|
|
@ -34,16 +34,18 @@ import org.elasticsearch.common.util.concurrent.EsExecutors;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.LongSupplier;
|
||||||
|
|
||||||
public class TransportMultiSearchAction extends HandledTransportAction<MultiSearchRequest, MultiSearchResponse> {
|
public class TransportMultiSearchAction extends HandledTransportAction<MultiSearchRequest, MultiSearchResponse> {
|
||||||
|
|
||||||
private final int availableProcessors;
|
private final int availableProcessors;
|
||||||
private final ClusterService clusterService;
|
private final ClusterService clusterService;
|
||||||
private final TransportAction<SearchRequest, SearchResponse> searchAction;
|
private final TransportAction<SearchRequest, SearchResponse> searchAction;
|
||||||
|
private final LongSupplier relativeTimeProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportMultiSearchAction(Settings settings, ThreadPool threadPool, TransportService transportService,
|
public TransportMultiSearchAction(Settings settings, ThreadPool threadPool, TransportService transportService,
|
||||||
|
@ -53,19 +55,23 @@ public class TransportMultiSearchAction extends HandledTransportAction<MultiSear
|
||||||
this.clusterService = clusterService;
|
this.clusterService = clusterService;
|
||||||
this.searchAction = searchAction;
|
this.searchAction = searchAction;
|
||||||
this.availableProcessors = EsExecutors.numberOfProcessors(settings);
|
this.availableProcessors = EsExecutors.numberOfProcessors(settings);
|
||||||
|
this.relativeTimeProvider = System::nanoTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
TransportMultiSearchAction(ThreadPool threadPool, ActionFilters actionFilters, TransportService transportService,
|
TransportMultiSearchAction(ThreadPool threadPool, ActionFilters actionFilters, TransportService transportService,
|
||||||
ClusterService clusterService, TransportAction<SearchRequest, SearchResponse> searchAction,
|
ClusterService clusterService, TransportAction<SearchRequest, SearchResponse> searchAction,
|
||||||
IndexNameExpressionResolver resolver, int availableProcessors) {
|
IndexNameExpressionResolver resolver, int availableProcessors, LongSupplier relativeTimeProvider) {
|
||||||
super(Settings.EMPTY, MultiSearchAction.NAME, threadPool, transportService, actionFilters, resolver, MultiSearchRequest::new);
|
super(Settings.EMPTY, MultiSearchAction.NAME, threadPool, transportService, actionFilters, resolver, MultiSearchRequest::new);
|
||||||
this.clusterService = clusterService;
|
this.clusterService = clusterService;
|
||||||
this.searchAction = searchAction;
|
this.searchAction = searchAction;
|
||||||
this.availableProcessors = availableProcessors;
|
this.availableProcessors = availableProcessors;
|
||||||
|
this.relativeTimeProvider = relativeTimeProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doExecute(MultiSearchRequest request, ActionListener<MultiSearchResponse> listener) {
|
protected void doExecute(MultiSearchRequest request, ActionListener<MultiSearchResponse> listener) {
|
||||||
|
final long relativeStartTime = relativeTimeProvider.getAsLong();
|
||||||
|
|
||||||
ClusterState clusterState = clusterService.state();
|
ClusterState clusterState = clusterService.state();
|
||||||
clusterState.blocks().globalBlockedRaiseException(ClusterBlockLevel.READ);
|
clusterState.blocks().globalBlockedRaiseException(ClusterBlockLevel.READ);
|
||||||
|
|
||||||
|
@ -85,7 +91,7 @@ public class TransportMultiSearchAction extends HandledTransportAction<MultiSear
|
||||||
final AtomicInteger responseCounter = new AtomicInteger(numRequests);
|
final AtomicInteger responseCounter = new AtomicInteger(numRequests);
|
||||||
int numConcurrentSearches = Math.min(numRequests, maxConcurrentSearches);
|
int numConcurrentSearches = Math.min(numRequests, maxConcurrentSearches);
|
||||||
for (int i = 0; i < numConcurrentSearches; i++) {
|
for (int i = 0; i < numConcurrentSearches; i++) {
|
||||||
executeSearch(searchRequestSlots, responses, responseCounter, listener);
|
executeSearch(searchRequestSlots, responses, responseCounter, listener, relativeStartTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,11 +117,12 @@ public class TransportMultiSearchAction extends HandledTransportAction<MultiSear
|
||||||
* @param responseCounter incremented on each response
|
* @param responseCounter incremented on each response
|
||||||
* @param listener the listener attached to the multi-search request
|
* @param listener the listener attached to the multi-search request
|
||||||
*/
|
*/
|
||||||
private void executeSearch(
|
void executeSearch(
|
||||||
final Queue<SearchRequestSlot> requests,
|
final Queue<SearchRequestSlot> requests,
|
||||||
final AtomicArray<MultiSearchResponse.Item> responses,
|
final AtomicArray<MultiSearchResponse.Item> responses,
|
||||||
final AtomicInteger responseCounter,
|
final AtomicInteger responseCounter,
|
||||||
final ActionListener<MultiSearchResponse> listener) {
|
final ActionListener<MultiSearchResponse> listener,
|
||||||
|
final long relativeStartTime) {
|
||||||
SearchRequestSlot request = requests.poll();
|
SearchRequestSlot request = requests.poll();
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
/*
|
/*
|
||||||
|
@ -155,16 +162,25 @@ public class TransportMultiSearchAction extends HandledTransportAction<MultiSear
|
||||||
} else {
|
} else {
|
||||||
if (thread == Thread.currentThread()) {
|
if (thread == Thread.currentThread()) {
|
||||||
// we are on the same thread, we need to fork to another thread to avoid recursive stack overflow on a single thread
|
// we are on the same thread, we need to fork to another thread to avoid recursive stack overflow on a single thread
|
||||||
threadPool.generic().execute(() -> executeSearch(requests, responses, responseCounter, listener));
|
threadPool.generic()
|
||||||
|
.execute(() -> executeSearch(requests, responses, responseCounter, listener, relativeStartTime));
|
||||||
} else {
|
} else {
|
||||||
// we are on a different thread (we went asynchronous), it's safe to recurse
|
// we are on a different thread (we went asynchronous), it's safe to recurse
|
||||||
executeSearch(requests, responses, responseCounter, listener);
|
executeSearch(requests, responses, responseCounter, listener, relativeStartTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finish() {
|
private void finish() {
|
||||||
listener.onResponse(new MultiSearchResponse(responses.toArray(new MultiSearchResponse.Item[responses.length()])));
|
listener.onResponse(new MultiSearchResponse(responses.toArray(new MultiSearchResponse.Item[responses.length()]),
|
||||||
|
buildTookInMillis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds how long it took to execute the msearch.
|
||||||
|
*/
|
||||||
|
private long buildTookInMillis() {
|
||||||
|
return TimeUnit.NANOSECONDS.toMillis(relativeTimeProvider.getAsLong() - relativeStartTime);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -178,7 +194,5 @@ public class TransportMultiSearchAction extends HandledTransportAction<MultiSear
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.responseSlot = responseSlot;
|
this.responseSlot = responseSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,8 @@ public class ExpandSearchPhaseTests extends ESTestCase {
|
||||||
mSearchResponses.add(new MultiSearchResponse.Item(response, null));
|
mSearchResponses.add(new MultiSearchResponse.Item(response, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
listener.onResponse(new MultiSearchResponse(mSearchResponses.toArray(new MultiSearchResponse.Item[0])));
|
listener.onResponse(
|
||||||
|
new MultiSearchResponse(mSearchResponses.toArray(new MultiSearchResponse.Item[0]), randomIntBetween(1, 10000)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,10 +154,11 @@ public class ExpandSearchPhaseTests extends ESTestCase {
|
||||||
InternalSearchResponse internalSearchResponse = new InternalSearchResponse(collapsedHits,
|
InternalSearchResponse internalSearchResponse = new InternalSearchResponse(collapsedHits,
|
||||||
null, null, null, false, null, 1);
|
null, null, null, false, null, 1);
|
||||||
SearchResponse response = mockSearchPhaseContext.buildSearchResponse(internalSearchResponse, null);
|
SearchResponse response = mockSearchPhaseContext.buildSearchResponse(internalSearchResponse, null);
|
||||||
listener.onResponse(new MultiSearchResponse(new MultiSearchResponse.Item[]{
|
listener.onResponse(new MultiSearchResponse(
|
||||||
new MultiSearchResponse.Item(null, new RuntimeException("boom")),
|
new MultiSearchResponse.Item[]{
|
||||||
new MultiSearchResponse.Item(response, null)
|
new MultiSearchResponse.Item(null, new RuntimeException("boom")),
|
||||||
}));
|
new MultiSearchResponse.Item(response, null)
|
||||||
|
}, randomIntBetween(1, 10000)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.action.search;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.action.IndicesRequest;
|
||||||
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
|
import org.elasticsearch.action.support.TransportAction;
|
||||||
|
import org.elasticsearch.cluster.ClusterName;
|
||||||
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||||
|
import org.elasticsearch.cluster.service.ClusterService;
|
||||||
|
import org.elasticsearch.common.Randomness;
|
||||||
|
import org.elasticsearch.common.UUIDs;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.util.concurrent.AtomicArray;
|
||||||
|
import org.elasticsearch.tasks.TaskManager;
|
||||||
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.function.LongSupplier;
|
||||||
|
|
||||||
|
import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MultiSearch took time tests
|
||||||
|
*/
|
||||||
|
public class MultiSearchActionTookTests extends ESTestCase {
|
||||||
|
|
||||||
|
private ThreadPool threadPool;
|
||||||
|
private ClusterService clusterService;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
threadPool = new TestThreadPool("MultiSearchActionTookTests");
|
||||||
|
clusterService = createClusterService(threadPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
clusterService.close();
|
||||||
|
ThreadPool.terminate(threadPool, 30, TimeUnit.SECONDS);
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// test unit conversion using a controller clock
|
||||||
|
public void testTookWithControlledClock() throws Exception {
|
||||||
|
runTestTook(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// test using System#nanoTime
|
||||||
|
public void testTookWithRealClock() throws Exception {
|
||||||
|
runTestTook(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTestTook(boolean controlledClock) throws Exception {
|
||||||
|
MultiSearchRequest multiSearchRequest = new MultiSearchRequest().add(new SearchRequest());
|
||||||
|
AtomicLong expected = new AtomicLong();
|
||||||
|
|
||||||
|
TransportMultiSearchAction action = createTransportMultiSearchAction(controlledClock, expected);
|
||||||
|
|
||||||
|
action.doExecute(multiSearchRequest, new ActionListener<MultiSearchResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(MultiSearchResponse multiSearchResponse) {
|
||||||
|
if (controlledClock) {
|
||||||
|
assertThat(TimeUnit.MILLISECONDS.convert(expected.get(), TimeUnit.NANOSECONDS),
|
||||||
|
equalTo(multiSearchResponse.getTook().getMillis()));
|
||||||
|
} else {
|
||||||
|
assertThat(multiSearchResponse.getTook().getMillis(),
|
||||||
|
greaterThanOrEqualTo(TimeUnit.MILLISECONDS.convert(expected.get(), TimeUnit.NANOSECONDS)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private TransportMultiSearchAction createTransportMultiSearchAction(boolean controlledClock, AtomicLong expected) {
|
||||||
|
Settings settings = Settings.builder().put("node.name", TransportMultiSearchActionTests.class.getSimpleName()).build();
|
||||||
|
TaskManager taskManager = mock(TaskManager.class);
|
||||||
|
TransportService transportService = new TransportService(Settings.EMPTY, null, null, TransportService.NOOP_TRANSPORT_INTERCEPTOR,
|
||||||
|
boundAddress -> DiscoveryNode.createLocal(settings, boundAddress.publishAddress(), UUIDs.randomBase64UUID()), null) {
|
||||||
|
@Override
|
||||||
|
public TaskManager getTaskManager() {
|
||||||
|
return taskManager;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ActionFilters actionFilters = new ActionFilters(new HashSet<>());
|
||||||
|
ClusterService clusterService = mock(ClusterService.class);
|
||||||
|
when(clusterService.state()).thenReturn(ClusterState.builder(new ClusterName("test")).build());
|
||||||
|
IndexNameExpressionResolver resolver = new Resolver(Settings.EMPTY);
|
||||||
|
|
||||||
|
final int availableProcessors = Runtime.getRuntime().availableProcessors();
|
||||||
|
AtomicInteger counter = new AtomicInteger();
|
||||||
|
final List<String> threadPoolNames = Arrays.asList(ThreadPool.Names.GENERIC, ThreadPool.Names.SAME);
|
||||||
|
Randomness.shuffle(threadPoolNames);
|
||||||
|
final ExecutorService commonExecutor = threadPool.executor(threadPoolNames.get(0));
|
||||||
|
final Set<SearchRequest> requests = Collections.newSetFromMap(Collections.synchronizedMap(new IdentityHashMap<>()));
|
||||||
|
|
||||||
|
TransportAction<SearchRequest, SearchResponse> searchAction = new TransportAction<SearchRequest, SearchResponse>(Settings.EMPTY,
|
||||||
|
"action", threadPool, actionFilters, resolver, taskManager) {
|
||||||
|
@Override
|
||||||
|
protected void doExecute(SearchRequest request, ActionListener<SearchResponse> listener) {
|
||||||
|
requests.add(request);
|
||||||
|
commonExecutor.execute(() -> {
|
||||||
|
counter.decrementAndGet();
|
||||||
|
listener.onResponse(new SearchResponse());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (controlledClock) {
|
||||||
|
return new TransportMultiSearchAction(threadPool, actionFilters, transportService, clusterService, searchAction, resolver,
|
||||||
|
availableProcessors, expected::get) {
|
||||||
|
@Override
|
||||||
|
void executeSearch(final Queue<SearchRequestSlot> requests, final AtomicArray<MultiSearchResponse.Item> responses,
|
||||||
|
final AtomicInteger responseCounter, final ActionListener<MultiSearchResponse> listener, long startTimeInNanos) {
|
||||||
|
expected.set(1000000);
|
||||||
|
super.executeSearch(requests, responses, responseCounter, listener, startTimeInNanos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return new TransportMultiSearchAction(threadPool, actionFilters, transportService, clusterService, searchAction, resolver,
|
||||||
|
availableProcessors, System::nanoTime) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void executeSearch(final Queue<SearchRequestSlot> requests, final AtomicArray<MultiSearchResponse.Item> responses,
|
||||||
|
final AtomicInteger responseCounter, final ActionListener<MultiSearchResponse> listener, long startTimeInNanos) {
|
||||||
|
long elapsed = spinForAtLeastNMilliseconds(randomIntBetween(0, 10));
|
||||||
|
expected.set(elapsed);
|
||||||
|
super.executeSearch(requests, responses, responseCounter, listener, startTimeInNanos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Resolver extends IndexNameExpressionResolver {
|
||||||
|
|
||||||
|
Resolver(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] concreteIndexNames(ClusterState state, IndicesRequest request) {
|
||||||
|
return request.indices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -146,13 +146,16 @@ public class MultiSearchRequestTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testResponseErrorToXContent() throws IOException {
|
public void testResponseErrorToXContent() throws IOException {
|
||||||
|
long tookInMillis = randomIntBetween(1, 1000);
|
||||||
MultiSearchResponse response = new MultiSearchResponse(
|
MultiSearchResponse response = new MultiSearchResponse(
|
||||||
new MultiSearchResponse.Item[]{
|
new MultiSearchResponse.Item[] {
|
||||||
new MultiSearchResponse.Item(null, new IllegalStateException("foobar")),
|
new MultiSearchResponse.Item(null, new IllegalStateException("foobar")),
|
||||||
new MultiSearchResponse.Item(null, new IllegalStateException("baaaaaazzzz"))
|
new MultiSearchResponse.Item(null, new IllegalStateException("baaaaaazzzz"))
|
||||||
});
|
}, tookInMillis);
|
||||||
|
|
||||||
assertEquals("{\"responses\":["
|
assertEquals("{\"took\":"
|
||||||
|
+ tookInMillis
|
||||||
|
+ ",\"responses\":["
|
||||||
+ "{"
|
+ "{"
|
||||||
+ "\"error\":{\"root_cause\":[{\"type\":\"illegal_state_exception\",\"reason\":\"foobar\"}],"
|
+ "\"error\":{\"root_cause\":[{\"type\":\"illegal_state_exception\",\"reason\":\"foobar\"}],"
|
||||||
+ "\"type\":\"illegal_state_exception\",\"reason\":\"foobar\"},\"status\":500"
|
+ "\"type\":\"illegal_state_exception\",\"reason\":\"foobar\"},\"status\":500"
|
||||||
|
|
|
@ -102,8 +102,10 @@ public class TransportMultiSearchActionTests extends ESTestCase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TransportMultiSearchAction action =
|
|
||||||
new TransportMultiSearchAction(threadPool, actionFilters, transportService, clusterService, searchAction, resolver, 10);
|
TransportMultiSearchAction action =
|
||||||
|
new TransportMultiSearchAction(threadPool, actionFilters, transportService, clusterService, searchAction, resolver, 10,
|
||||||
|
System::nanoTime);
|
||||||
|
|
||||||
// Execute the multi search api and fail if we find an error after executing:
|
// Execute the multi search api and fail if we find an error after executing:
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue