Search in sources :

Example 46 with ActionListener

use of org.elasticsearch.action.ActionListener in project elasticsearch by elastic.

the class FetchSearchPhaseTests method testFetchDocsConcurrently.

public void testFetchDocsConcurrently() throws IOException, InterruptedException {
    int resultSetSize = randomIntBetween(0, 100);
    // we use at least 2 hits otherwise this is subject to single shard optimization and we trip an assert...
    // also numshards --> 1 hit per shard
    int numHits = randomIntBetween(2, 100);
    SearchPhaseController controller = new SearchPhaseController(Settings.EMPTY, BigArrays.NON_RECYCLING_INSTANCE, null);
    MockSearchPhaseContext mockSearchPhaseContext = new MockSearchPhaseContext(numHits);
    InitialSearchPhase.SearchPhaseResults<QuerySearchResultProvider> results = controller.newSearchPhaseResults(mockSearchPhaseContext.getRequest(), numHits);
    AtomicReference<SearchResponse> responseRef = new AtomicReference<>();
    for (int i = 0; i < numHits; i++) {
        QuerySearchResult queryResult = new QuerySearchResult(i, new SearchShardTarget("node1", new Index("test", "na"), 0));
        queryResult.topDocs(new TopDocs(1, new ScoreDoc[] { new ScoreDoc(i + 1, i) }, i), new DocValueFormat[0]);
        // the size of the result set
        queryResult.size(resultSetSize);
        results.consumeResult(i, queryResult);
    }
    SearchTransportService searchTransportService = new SearchTransportService(Settings.builder().put("search.remote.connect", false).build(), null, null) {

        @Override
        public void sendExecuteFetch(Transport.Connection connection, ShardFetchSearchRequest request, SearchTask task, ActionListener<FetchSearchResult> listener) {
            new Thread(() -> {
                FetchSearchResult fetchResult = new FetchSearchResult();
                fetchResult.hits(new SearchHits(new SearchHit[] { new SearchHit((int) (request.id() + 1)) }, 1, 100F));
                listener.onResponse(fetchResult);
            }).start();
        }
    };
    mockSearchPhaseContext.searchTransport = searchTransportService;
    CountDownLatch latch = new CountDownLatch(1);
    FetchSearchPhase phase = new FetchSearchPhase(results, controller, mockSearchPhaseContext, (searchResponse) -> new SearchPhase("test") {

        @Override
        public void run() throws IOException {
            responseRef.set(searchResponse);
            latch.countDown();
        }
    });
    assertEquals("fetch", phase.getName());
    phase.run();
    latch.await();
    mockSearchPhaseContext.assertNoFailure();
    assertNotNull(responseRef.get());
    assertEquals(numHits, responseRef.get().getHits().totalHits);
    assertEquals(Math.min(numHits, resultSetSize), responseRef.get().getHits().getHits().length);
    SearchHit[] hits = responseRef.get().getHits().getHits();
    for (int i = 0; i < hits.length; i++) {
        assertNotNull(hits[i]);
        assertEquals("index: " + i, numHits - i, hits[i].docId());
        assertEquals("index: " + i, numHits - 1 - i, (int) hits[i].getScore());
    }
    assertEquals(0, responseRef.get().getFailedShards());
    assertEquals(numHits, responseRef.get().getSuccessfulShards());
    // all non fetched results will be freed
    int sizeReleasedContexts = Math.max(0, numHits - resultSetSize);
    assertEquals(mockSearchPhaseContext.releasedSearchContexts.toString(), sizeReleasedContexts, mockSearchPhaseContext.releasedSearchContexts.size());
}
Also used : SearchHit(org.elasticsearch.search.SearchHit) QueryFetchSearchResult(org.elasticsearch.search.fetch.QueryFetchSearchResult) FetchSearchResult(org.elasticsearch.search.fetch.FetchSearchResult) Index(org.elasticsearch.index.Index) ScoreDoc(org.apache.lucene.search.ScoreDoc) TopDocs(org.apache.lucene.search.TopDocs) ShardFetchSearchRequest(org.elasticsearch.search.fetch.ShardFetchSearchRequest) SearchHits(org.elasticsearch.search.SearchHits) QuerySearchResultProvider(org.elasticsearch.search.query.QuerySearchResultProvider) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) ActionListener(org.elasticsearch.action.ActionListener) QuerySearchResult(org.elasticsearch.search.query.QuerySearchResult) SearchShardTarget(org.elasticsearch.search.SearchShardTarget)

Example 47 with ActionListener

use of org.elasticsearch.action.ActionListener in project elasticsearch by elastic.

the class FetchSearchPhaseTests method testExceptionFailsPhase.

public void testExceptionFailsPhase() throws IOException {
    MockSearchPhaseContext mockSearchPhaseContext = new MockSearchPhaseContext(2);
    SearchPhaseController controller = new SearchPhaseController(Settings.EMPTY, BigArrays.NON_RECYCLING_INSTANCE, null);
    InitialSearchPhase.SearchPhaseResults<QuerySearchResultProvider> results = controller.newSearchPhaseResults(mockSearchPhaseContext.getRequest(), 2);
    AtomicReference<SearchResponse> responseRef = new AtomicReference<>();
    int resultSetSize = randomIntBetween(2, 10);
    QuerySearchResult queryResult = new QuerySearchResult(123, new SearchShardTarget("node1", new Index("test", "na"), 0));
    queryResult.topDocs(new TopDocs(1, new ScoreDoc[] { new ScoreDoc(42, 1.0F) }, 2.0F), new DocValueFormat[0]);
    // the size of the result set
    queryResult.size(resultSetSize);
    results.consumeResult(0, queryResult);
    queryResult = new QuerySearchResult(321, new SearchShardTarget("node2", new Index("test", "na"), 1));
    queryResult.topDocs(new TopDocs(1, new ScoreDoc[] { new ScoreDoc(84, 2.0F) }, 2.0F), new DocValueFormat[0]);
    queryResult.size(resultSetSize);
    results.consumeResult(1, queryResult);
    AtomicInteger numFetches = new AtomicInteger(0);
    SearchTransportService searchTransportService = new SearchTransportService(Settings.builder().put("search.remote.connect", false).build(), null, null) {

        @Override
        public void sendExecuteFetch(Transport.Connection connection, ShardFetchSearchRequest request, SearchTask task, ActionListener<FetchSearchResult> listener) {
            FetchSearchResult fetchResult = new FetchSearchResult();
            if (numFetches.incrementAndGet() == 1) {
                throw new RuntimeException("BOOM");
            }
            if (request.id() == 321) {
                fetchResult.hits(new SearchHits(new SearchHit[] { new SearchHit(84) }, 1, 2.0F));
            } else {
                assertEquals(request, 123);
                fetchResult.hits(new SearchHits(new SearchHit[] { new SearchHit(42) }, 1, 1.0F));
            }
            listener.onResponse(fetchResult);
        }
    };
    mockSearchPhaseContext.searchTransport = searchTransportService;
    FetchSearchPhase phase = new FetchSearchPhase(results, controller, mockSearchPhaseContext, (searchResponse) -> new SearchPhase("test") {

        @Override
        public void run() throws IOException {
            responseRef.set(searchResponse);
        }
    });
    assertEquals("fetch", phase.getName());
    phase.run();
    assertNotNull(mockSearchPhaseContext.phaseFailure.get());
    assertEquals(mockSearchPhaseContext.phaseFailure.get().getMessage(), "BOOM");
    assertNull(responseRef.get());
    assertTrue(mockSearchPhaseContext.releasedSearchContexts.isEmpty());
}
Also used : SearchHit(org.elasticsearch.search.SearchHit) QueryFetchSearchResult(org.elasticsearch.search.fetch.QueryFetchSearchResult) FetchSearchResult(org.elasticsearch.search.fetch.FetchSearchResult) Index(org.elasticsearch.index.Index) ScoreDoc(org.apache.lucene.search.ScoreDoc) TopDocs(org.apache.lucene.search.TopDocs) ShardFetchSearchRequest(org.elasticsearch.search.fetch.ShardFetchSearchRequest) SearchHits(org.elasticsearch.search.SearchHits) QuerySearchResultProvider(org.elasticsearch.search.query.QuerySearchResultProvider) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) ActionListener(org.elasticsearch.action.ActionListener) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) QuerySearchResult(org.elasticsearch.search.query.QuerySearchResult) SearchShardTarget(org.elasticsearch.search.SearchShardTarget)

Example 48 with ActionListener

use of org.elasticsearch.action.ActionListener in project elasticsearch by elastic.

the class SearchAsyncActionTests method testFanOutAndCollect.

public void testFanOutAndCollect() throws InterruptedException {
    SearchRequest request = new SearchRequest();
    CountDownLatch latch = new CountDownLatch(1);
    AtomicReference<TestSearchResponse> response = new AtomicReference<>();
    ActionListener<SearchResponse> responseListener = new ActionListener<SearchResponse>() {

        @Override
        public void onResponse(SearchResponse searchResponse) {
            response.set((TestSearchResponse) searchResponse);
        }

        @Override
        public void onFailure(Exception e) {
            logger.warn("test failed", e);
            fail(e.getMessage());
        }
    };
    DiscoveryNode primaryNode = new DiscoveryNode("node_1", buildNewFakeTransportAddress(), Version.CURRENT);
    DiscoveryNode replicaNode = new DiscoveryNode("node_2", buildNewFakeTransportAddress(), Version.CURRENT);
    Map<DiscoveryNode, Set<Long>> nodeToContextMap = new HashMap<>();
    AtomicInteger contextIdGenerator = new AtomicInteger(0);
    GroupShardsIterator shardsIter = getShardsIter("idx", randomIntBetween(1, 10), randomBoolean(), primaryNode, replicaNode);
    AtomicInteger numFreedContext = new AtomicInteger();
    SearchTransportService transportService = new SearchTransportService(Settings.EMPTY, new ClusterSettings(Settings.EMPTY, Collections.singleton(RemoteClusterService.REMOTE_CLUSTERS_SEEDS)), null) {

        @Override
        public void sendFreeContext(Transport.Connection connection, long contextId, SearchRequest request) {
            numFreedContext.incrementAndGet();
            assertTrue(nodeToContextMap.containsKey(connection.getNode()));
            assertTrue(nodeToContextMap.get(connection.getNode()).remove(contextId));
        }
    };
    Map<String, Transport.Connection> lookup = new HashMap<>();
    lookup.put(primaryNode.getId(), new MockConnection(primaryNode));
    lookup.put(replicaNode.getId(), new MockConnection(replicaNode));
    Map<String, AliasFilter> aliasFilters = Collections.singletonMap("_na_", new AliasFilter(null, Strings.EMPTY_ARRAY));
    AbstractSearchAsyncAction asyncAction = new AbstractSearchAsyncAction<TestSearchPhaseResult>("test", logger, transportService, lookup::get, aliasFilters, Collections.emptyMap(), null, request, responseListener, shardsIter, 0, 0, null, new InitialSearchPhase.SearchPhaseResults<>(shardsIter.size())) {

        TestSearchResponse response = new TestSearchResponse();

        @Override
        protected void executePhaseOnShard(ShardIterator shardIt, ShardRouting shard, ActionListener<TestSearchPhaseResult> listener) {
            assertTrue("shard: " + shard.shardId() + " has been queried twice", response.queried.add(shard.shardId()));
            Transport.Connection connection = getConnection(shard.currentNodeId());
            TestSearchPhaseResult testSearchPhaseResult = new TestSearchPhaseResult(contextIdGenerator.incrementAndGet(), connection.getNode());
            Set<Long> ids = nodeToContextMap.computeIfAbsent(connection.getNode(), (n) -> new HashSet<>());
            ids.add(testSearchPhaseResult.id);
            if (randomBoolean()) {
                listener.onResponse(testSearchPhaseResult);
            } else {
                new Thread(() -> listener.onResponse(testSearchPhaseResult)).start();
            }
        }

        @Override
        protected SearchPhase getNextPhase(SearchPhaseResults<TestSearchPhaseResult> results, SearchPhaseContext context) {
            return new SearchPhase("test") {

                @Override
                public void run() throws IOException {
                    for (int i = 0; i < results.getNumShards(); i++) {
                        TestSearchPhaseResult result = results.results.get(i);
                        assertEquals(result.node.getId(), result.shardTarget().getNodeId());
                        sendReleaseSearchContext(result.id(), new MockConnection(result.node));
                    }
                    responseListener.onResponse(response);
                    latch.countDown();
                }
            };
        }
    };
    asyncAction.start();
    latch.await();
    assertNotNull(response.get());
    assertFalse(nodeToContextMap.isEmpty());
    assertTrue(nodeToContextMap.toString(), nodeToContextMap.containsKey(primaryNode) || nodeToContextMap.containsKey(replicaNode));
    assertEquals(shardsIter.size(), numFreedContext.get());
    if (nodeToContextMap.containsKey(primaryNode)) {
        assertTrue(nodeToContextMap.get(primaryNode).toString(), nodeToContextMap.get(primaryNode).isEmpty());
    } else {
        assertTrue(nodeToContextMap.get(replicaNode).toString(), nodeToContextMap.get(replicaNode).isEmpty());
    }
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) AliasFilter(org.elasticsearch.search.internal.AliasFilter) HashSet(java.util.HashSet) Set(java.util.Set) ClusterSettings(org.elasticsearch.common.settings.ClusterSettings) HashMap(java.util.HashMap) ShardIterator(org.elasticsearch.cluster.routing.ShardIterator) PlainShardIterator(org.elasticsearch.cluster.routing.PlainShardIterator) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) IOException(java.io.IOException) TransportException(org.elasticsearch.transport.TransportException) ActionListener(org.elasticsearch.action.ActionListener) GroupShardsIterator(org.elasticsearch.cluster.routing.GroupShardsIterator) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting) Transport(org.elasticsearch.transport.Transport)

Example 49 with ActionListener

use of org.elasticsearch.action.ActionListener in project elasticsearch by elastic.

the class TransportMultiSearchActionTests method testBatchExecute.

public void testBatchExecute() throws Exception {
    // Initialize dependencies of TransportMultiSearchAction
    Settings settings = Settings.builder().put("node.name", TransportMultiSearchActionTests.class.getSimpleName()).build();
    ActionFilters actionFilters = mock(ActionFilters.class);
    when(actionFilters.filters()).thenReturn(new ActionFilter[0]);
    ThreadPool threadPool = new ThreadPool(settings);
    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;
        }
    };
    ClusterService clusterService = mock(ClusterService.class);
    when(clusterService.state()).thenReturn(ClusterState.builder(new ClusterName("test")).build());
    IndexNameExpressionResolver resolver = new IndexNameExpressionResolver(Settings.EMPTY);
    // Keep track of the number of concurrent searches started by multi search api,
    // and if there are more searches than is allowed create an error and remember that.
    int maxAllowedConcurrentSearches = scaledRandomIntBetween(1, 16);
    AtomicInteger counter = new AtomicInteger();
    AtomicReference<AssertionError> errorHolder = new AtomicReference<>();
    // randomize whether or not requests are executed asynchronously
    final List<String> threadPoolNames = Arrays.asList(ThreadPool.Names.GENERIC, ThreadPool.Names.SAME);
    Randomness.shuffle(threadPoolNames);
    final ExecutorService commonExecutor = threadPool.executor(threadPoolNames.get(0));
    final ExecutorService rarelyExecutor = threadPool.executor(threadPoolNames.get(1));
    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);
            int currentConcurrentSearches = counter.incrementAndGet();
            if (currentConcurrentSearches > maxAllowedConcurrentSearches) {
                errorHolder.set(new AssertionError("Current concurrent search [" + currentConcurrentSearches + "] is higher than is allowed [" + maxAllowedConcurrentSearches + "]"));
            }
            final ExecutorService executorService = rarely() ? rarelyExecutor : commonExecutor;
            executorService.execute(() -> {
                counter.decrementAndGet();
                listener.onResponse(new SearchResponse());
            });
        }
    };
    TransportMultiSearchAction action = new TransportMultiSearchAction(threadPool, actionFilters, transportService, clusterService, searchAction, resolver, 10);
    // Execute the multi search api and fail if we find an error after executing:
    try {
        /*
             * Allow for a large number of search requests in a single batch as previous implementations could stack overflow if the number
             * of requests in a single batch was large
             */
        int numSearchRequests = scaledRandomIntBetween(1, 8192);
        MultiSearchRequest multiSearchRequest = new MultiSearchRequest();
        multiSearchRequest.maxConcurrentSearchRequests(maxAllowedConcurrentSearches);
        for (int i = 0; i < numSearchRequests; i++) {
            multiSearchRequest.add(new SearchRequest());
        }
        MultiSearchResponse response = action.execute(multiSearchRequest).actionGet();
        assertThat(response.getResponses().length, equalTo(numSearchRequests));
        assertThat(requests.size(), equalTo(numSearchRequests));
        assertThat(errorHolder.get(), nullValue());
    } finally {
        assertTrue(ESTestCase.terminate(threadPool));
    }
}
Also used : IdentityHashMap(java.util.IdentityHashMap) ThreadPool(org.elasticsearch.threadpool.ThreadPool) ClusterName(org.elasticsearch.cluster.ClusterName) Settings(org.elasticsearch.common.settings.Settings) AtomicReference(java.util.concurrent.atomic.AtomicReference) ActionFilters(org.elasticsearch.action.support.ActionFilters) TransportAction(org.elasticsearch.action.support.TransportAction) TaskManager(org.elasticsearch.tasks.TaskManager) ClusterService(org.elasticsearch.cluster.service.ClusterService) ActionListener(org.elasticsearch.action.ActionListener) TransportService(org.elasticsearch.transport.TransportService) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorService(java.util.concurrent.ExecutorService) IndexNameExpressionResolver(org.elasticsearch.cluster.metadata.IndexNameExpressionResolver)

Example 50 with ActionListener

use of org.elasticsearch.action.ActionListener in project elasticsearch by elastic.

the class ContextPreservingActionListenerTests method testOriginalContextIsWhenListenerThrows.

public void testOriginalContextIsWhenListenerThrows() throws Exception {
    try (ThreadContext threadContext = new ThreadContext(Settings.EMPTY)) {
        final boolean nonEmptyContext = randomBoolean();
        if (nonEmptyContext) {
            threadContext.putHeader("not empty", "value");
        }
        ContextPreservingActionListener<Void> actionListener;
        try (ThreadContext.StoredContext ignore = threadContext.stashContext()) {
            threadContext.putHeader("foo", "bar");
            actionListener = new ContextPreservingActionListener<>(threadContext.newRestorableContext(true), new ActionListener<Void>() {

                @Override
                public void onResponse(Void aVoid) {
                    assertEquals("bar", threadContext.getHeader("foo"));
                    assertNull(threadContext.getHeader("not empty"));
                    throw new RuntimeException("onResponse called");
                }

                @Override
                public void onFailure(Exception e) {
                    assertEquals("bar", threadContext.getHeader("foo"));
                    assertNull(threadContext.getHeader("not empty"));
                    throw new RuntimeException("onFailure called");
                }
            });
        }
        assertNull(threadContext.getHeader("foo"));
        assertEquals(nonEmptyContext ? "value" : null, threadContext.getHeader("not empty"));
        RuntimeException e = expectThrows(RuntimeException.class, () -> actionListener.onResponse(null));
        assertEquals("onResponse called", e.getMessage());
        assertNull(threadContext.getHeader("foo"));
        assertEquals(nonEmptyContext ? "value" : null, threadContext.getHeader("not empty"));
        e = expectThrows(RuntimeException.class, () -> actionListener.onFailure(null));
        assertEquals("onFailure called", e.getMessage());
        assertNull(threadContext.getHeader("foo"));
        assertEquals(nonEmptyContext ? "value" : null, threadContext.getHeader("not empty"));
    }
}
Also used : ActionListener(org.elasticsearch.action.ActionListener) ThreadContext(org.elasticsearch.common.util.concurrent.ThreadContext) IOException(java.io.IOException)

Aggregations

ActionListener (org.elasticsearch.action.ActionListener)58 IOException (java.io.IOException)25 ThreadPool (org.elasticsearch.threadpool.ThreadPool)19 AtomicReference (java.util.concurrent.atomic.AtomicReference)18 Settings (org.elasticsearch.common.settings.Settings)18 ClusterState (org.elasticsearch.cluster.ClusterState)17 Index (org.elasticsearch.index.Index)13 ShardId (org.elasticsearch.index.shard.ShardId)13 IndexNameExpressionResolver (org.elasticsearch.cluster.metadata.IndexNameExpressionResolver)12 TransportService (org.elasticsearch.transport.TransportService)12 CountDownLatch (java.util.concurrent.CountDownLatch)11 ArrayList (java.util.ArrayList)10 TimeValue (org.elasticsearch.common.unit.TimeValue)10 CrateUnitTest (io.crate.test.integration.CrateUnitTest)9 List (java.util.List)9 ActionFilters (org.elasticsearch.action.support.ActionFilters)9 EsRejectedExecutionException (org.elasticsearch.common.util.concurrent.EsRejectedExecutionException)9 TransportException (org.elasticsearch.transport.TransportException)9 DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)8 ShardResponse (io.crate.executor.transport.ShardResponse)7