Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StackOverflowError while RestClient.retryIfPossible #25306

Closed
liudunxu opened this issue Jun 20, 2017 · 17 comments
Closed

StackOverflowError while RestClient.retryIfPossible #25306

liudunxu opened this issue Jun 20, 2017 · 17 comments
Labels
>bug :Clients/Java Low Level REST Client Minimal dependencies Java Client for Elasticsearch Team:Data Management Meta label for data/management team

Comments

@liudunxu
Copy link

liudunxu commented Jun 20, 2017

Elasticsearch version:

Elasticsearch 5.2.2

JVM version (java -version):

1.8

Description of the problem including expected versus actual behavior:

RestClient client = RestClient.builder("a","b","c");
RestClient.performRequestAsync(....)

throws exception

java.lang.StackOverflowError: null
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:131)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.failed(AbstractClientExchangeHandler.java:419)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.connectionRequestFailed(AbstractClientExchangeHandler.java:335)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.access$100(AbstractClientExchangeHandler.java:62)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler$1.failed(AbstractClientExchangeHandler.java:378)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager$InternalPoolEntryCallback.failed(PoolingNHttpClientConnectionManager.java:504)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.fireCallbacks(AbstractNIOConnPool.java:454)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:286)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:266)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:363)
       	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:125)
       	at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141)
       	at org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(CloseableHttpAsyncClient.java:68)
       	at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:300)
       	at org.elasticsearch.client.RestClient.access$600(RestClient.java:84)
       	at org.elasticsearch.client.RestClient$1.retryIfPossible(RestClient.java:350)
       	at org.elasticsearch.client.RestClient$1.failed(RestClient.java:332)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.failed(AbstractClientExchangeHandler.java:419)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.connectionRequestFailed(AbstractClientExchangeHandler.java:335)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.access$100(AbstractClientExchangeHandler.java:62)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler$1.failed(AbstractClientExchangeHandler.java:378)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager$InternalPoolEntryCallback.failed(PoolingNHttpClientConnectionManager.java:504)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.fireCallbacks(AbstractNIOConnPool.java:454)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:286)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:266)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:363)
       	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:125)
.
.
.

I have no idea of the reason of this exception.Can anyone add a attribute "maxRetryTimes" to the RestClient or other way to solve this problem?

More Details

  1. only 3 hosts added to the restclient
  2. never call restclient.setHosts in my own code
  3. It calls the method retryIfPossible more than 20 times
  4. It seldom happens.
@abeyad
Copy link

abeyad commented Jun 20, 2017

@javanna what do you think about this one?

@tlrx tlrx added :Clients/Java Low Level REST Client Minimal dependencies Java Client for Elasticsearch feedback_needed labels Jun 22, 2017
@tlrx
Copy link
Member

tlrx commented Jun 22, 2017

I can't reproduce the issue. The RestClient should try to execute the request multiple times for 30s and then it should gives up and calls the onFailure() method of the listener.

Could you please share with us the Java code of how the RestClient is used?

Also, could you provide more logs (in order to see if there's an exception somewhere)?

Finally, can you try to reproduce using a more recent version? There's a small fix (#23307) I think of that should have been part of 5.2.2 but apparently it's not.

@liudunxu
Copy link
Author

my shorthanded code is below.

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpHost;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseListener;
import org.elasticsearch.client.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.ImmutableList;

public class Test222 {

    private static final Logger logger = LoggerFactory.getLogger(Test222.class);
    private static final int CONNECT_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(60);
    private static final int SOCKET_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(60);
    private static final int MAX_RETRY_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(60);
    private static final int THREAD_SIZE = 200;

    private static final ConcurrentHashMap<String, RestClient> map = new ConcurrentHashMap<>();

    public static void main(String[] args) throws InterruptedException {

        RestClient client1 = buildRestClient(
                ImmutableList.of("cluster1-host1", "cluster1-host2", "cluster1-host3"));

        RestClient client2 = buildRestClient(
                ImmutableList.of("cluster2-host1", "cluster2-host2", "cluster2-host3"));

        ErrorLoggingListener errorLogger1 = new ErrorLoggingListener("cluster1", "index1");
        ErrorLoggingListener errorLogger2 = new ErrorLoggingListener("cluster2", "index2");

        ExecutorService executorService = Executors.newFixedThreadPool(1000);

        for (int i = 0; i < 200; i++) {
            executorService.submit(() -> {
                client1.performRequestAsync("methods", "endpoint", errorLogger1);
                client2.performRequestAsync("methods", "endpoint", errorLogger2);
            });
        }

        for (int i = 0; i < 200; i++) {
            executorService.submit(() -> {
                client1.performRequestAsync("methods", "endpoint", errorLogger1);
            });
        }
    }

    private static class ErrorLoggingListener implements ResponseListener {

        private final String clusterName;
        private final String indexName;

        ErrorLoggingListener(String clusterName, String indexName) {
            this.clusterName = clusterName;
            this.indexName = indexName;
        }

        @Override
        public void onSuccess(Response response) {

        }

        @Override
        public void onFailure(Exception exception) {
            logger.error("{} {} es ops.", clusterName, indexName, exception);
        }
    }

    private static RestClient buildRestClient(List<String> servers) {
        HttpHost[] hosts = servers.stream().map(HttpHost::create).toArray(HttpHost[]::new);
        return RestClient.builder(hosts)
                .setRequestConfigCallback(builder -> builder.setConnectTimeout(CONNECT_TIMEOUT)
                        .setSocketTimeout(SOCKET_TIMEOUT))
                .setHttpClientConfigCallback(builder -> builder.setDefaultIOReactorConfig(
                        IOReactorConfig.custom().setIoThreadCount(THREAD_SIZE).build()))
                .setMaxRetryTimeoutMillis(MAX_RETRY_TIMEOUT).build();
    }

}

@liudunxu
Copy link
Author

below is my stack trace,It seldom happen. but when it is happeing,many errors like this is thrown :

ERROR I/O dispatcher 46 (DefaultUncaughtExceptionHandlerRegistry.java:23) - uncaught exception occurred on thread [Thread[I/O dispatcher 46,5,main]]
java.lang.StackOverflowError: null
       	at java.util.concurrent.ConcurrentHashMap.putIfAbsent(ConcurrentHashMap.java:1535)
       	at org.elasticsearch.client.RestClient.onFailure(RestClient.java:437)
       	at org.elasticsearch.client.RestClient.access$400(RestClient.java:84)
       	at org.elasticsearch.client.RestClient$1.failed(RestClient.java:331)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.failed(AbstractClientExchangeHandler.java:419)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.connectionRequestFailed(AbstractClientExchangeHandler.java:335)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.access$100(AbstractClientExchangeHandler.java:62)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler$1.failed(AbstractClientExchangeHandler.java:378)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager$InternalPoolEntryCallback.failed(PoolingNHttpClientConnectionManager.java:504)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.fireCallbacks(AbstractNIOConnPool.java:454)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:286)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:266)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:363)
       	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:125)
       	at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141)
       	at org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(CloseableHttpAsyncClient.java:68)
       	at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:300)
       	at org.elasticsearch.client.RestClient.access$600(RestClient.java:84)
       	at org.elasticsearch.client.RestClient$1.retryIfPossible(RestClient.java:350)
       	at org.elasticsearch.client.RestClient$1.failed(RestClient.java:332)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.failed(AbstractClientExchangeHandler.java:419)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.connectionRequestFailed(AbstractClientExchangeHandler.java:335)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.access$100(AbstractClientExchangeHandler.java:62)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler$1.failed(AbstractClientExchangeHandler.java:378)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager$InternalPoolEntryCallback.failed(PoolingNHttpClientConnectionManager.java:504)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.fireCallbacks(AbstractNIOConnPool.java:454)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:286)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:266)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:363)
       	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:125)
       	at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141)
       	at org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(CloseableHttpAsyncClient.java:68)
       	at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:300)
       	at org.elasticsearch.client.RestClient.access$600(RestClient.java:84)
       	at org.elasticsearch.client.RestClient$1.retryIfPossible(RestClient.java:350)
       	at org.elasticsearch.client.RestClient$1.failed(RestClient.java:332)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.failed(AbstractClientExchangeHandler.java:419)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.connectionRequestFailed(AbstractClientExchangeHandler.java:335)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.access$100(AbstractClientExchangeHandler.java:62)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler$1.failed(AbstractClientExchangeHandler.java:378)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager$InternalPoolEntryCallback.failed(PoolingNHttpClientConnectionManager.java:504)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.fireCallbacks(AbstractNIOConnPool.java:454)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:286)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:266)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:363)
       	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:125)
       	at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141)
       	at org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(CloseableHttpAsyncClient.java:68)
       	at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:300)
       	at org.elasticsearch.client.RestClient.access$600(RestClient.java:84)
       	at org.elasticsearch.client.RestClient$1.retryIfPossible(RestClient.java:350)
       	at org.elasticsearch.client.RestClient$1.failed(RestClient.java:332)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.failed(AbstractClientExchangeHandler.java:419)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.connectionRequestFailed(AbstractClientExchangeHandler.java:335)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.access$100(AbstractClientExchangeHandler.java:62)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler$1.failed(AbstractClientExchangeHandler.java:378)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager$InternalPoolEntryCallback.failed(PoolingNHttpClientConnectionManager.java:504)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.fireCallbacks(AbstractNIOConnPool.java:454)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:286)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:266)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:363)
       	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:125)
       	at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141)
       	at org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(CloseableHttpAsyncClient.java:68)
       	at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:300)
       	at org.elasticsearch.client.RestClient.access$600(RestClient.java:84)
       	at org.elasticsearch.client.RestClient$1.retryIfPossible(RestClient.java:350)
       	at org.elasticsearch.client.RestClient$1.failed(RestClient.java:332)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.failed(AbstractClientExchangeHandler.java:419)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.connectionRequestFailed(AbstractClientExchangeHandler.java:335)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.access$100(AbstractClientExchangeHandler.java:62)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler$1.failed(AbstractClientExchangeHandler.java:378)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager$InternalPoolEntryCallback.failed(PoolingNHttpClientConnectionManager.java:504)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.fireCallbacks(AbstractNIOConnPool.java:454)
       	at org.apache.http.nio.pool.AbstractNIOConnPool.lease(AbstractNIOConnPool.java:286)
       	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.requestConnection(PoolingNHttpClientConnectionManager.java:266)
       	at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.requestConnection(AbstractClientExchangeHandler.java:363)
       	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.start(DefaultClientExchangeHandlerImpl.java:125)
       	at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:141)
       	at org.apache.http.impl.nio.client.CloseableHttpAsyncClient.execute(CloseableHttpAsyncClient.java:68)
       	at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:300)
       	at org.elasticsearch.client.RestClient.access$600(RestClient.java:84)
       	at org.elasticsearch.client.RestClient$1.retryIfPossible(RestClient.java:350)
       	at org.elasticsearch.client.RestClient$1.failed(RestClient.java:332)
       	at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:134)

@tlrx
Copy link
Member

tlrx commented Jun 23, 2017

Thanks for the information. Sadly I still can't reproduce but I'd be happy if you can test against with a more recent version.

@colings86
Copy link
Contributor

No further feedback. If you are able to reproduce this on the latest version please comment here with details and we can re-open

@javanna
Copy link
Member

javanna commented Jul 26, 2017

I prefer to leave this open for now, I want to try and dig deeper to see if I can find what is causing it.

@liudunxu
Copy link
Author

liudunxu commented Aug 3, 2017

can RestClientBuilder provide a method maxRetryTimes?

@liudunxu
Copy link
Author

liudunxu commented Aug 3, 2017

I added FailureListener.

RestClient.FailureListener() {
                    @Override
                    public void onFailure(HttpHost host) {
                        logger.warn("es host failed. host: {}", host);
                    }
}

When it failed,the logger is below:
2017-08-03 18:16:23.819 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostA:9200
2017-08-03 18:16:23.819 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostB:9200
2017-08-03 18:16:23.819 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostA:9200
2017-08-03 18:16:23.819 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostA:9200
2017-08-03 18:16:23.820 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostB:9200
2017-08-03 18:16:23.820 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostB:9200
2017-08-03 18:16:23.820 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostA:9200
2017-08-03 18:16:23.820 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostC:9200
2017-08-03 18:16:23.821 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostB:9200
2017-08-03 18:16:23.821 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostA:9200
2017-08-03 18:16:23.821 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostC:9200
2017-08-03 18:16:23.822 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostC:9200
2017-08-03 18:16:23.823 WARN I/O dispatcher 284 (ElasticSearchHolder.java:121) - es host failed. host: http://HostC:9200

@javanna
Copy link
Member

javanna commented Aug 3, 2017

hi @liudunxu the RestClient should not retry a request indefinitely. When a node fails, it will simply retry all the other nodes in the worst case, it should not retry the same node more than once for the same request. Sorry I didn't have time to dig into this yet, I will soon. I think that providing maxRetryTimes is not the right solution here, it shouldn't be necessary and if it is it's probably due to a bug.

@nik9000
Copy link
Member

nik9000 commented Mar 13, 2018

@javanna is this still a thing?

@javanna
Copy link
Member

javanna commented Mar 13, 2018

@nik9000 potentially, no progress made :(

@mohitrajvardhan17
Copy link

Hi @liudunxu can you to check if the "cluster2-host1", "cluster2-host2" & "cluster2-host3" are reachable from the host where the mentioned script is running.I am not sure about the timeout related with the calls but you can give it a look.I am also checking it from my end.

@liudunxu
Copy link
Author

@mohitrajvardhan17 yes, the three es hosts are reachable.I think it may be something wrong with the es instance's load. I have checked the es instance‘s log,When the server is under full GC, the error occurs frequently. Then I expand the cluster to six instances.And now it seldom happens.

@colings86 colings86 added the >bug label Apr 24, 2018
@javanna javanna removed their assignment Jul 16, 2018
@fabianmurariu
Copy link

fabianmurariu commented Mar 12, 2019

Here is what I think needs to happen for this issue to trigger (tested on 5.4)

  1. You need a large enough maxRetryTimeoutMillis
  2. Apache http client decides to run your callback on the same thread (for some reason)
  3. You have large number of hosts

Add the below code to RestClientTest on the 5.4 branch and you should see StackOverflow

    public void testPerformAsyncThatLoops() throws Exception {
        RestClient.SyncResponseListener listener = new RestClient.SyncResponseListener(10000);
        // Many hosts in your cluster
        ArrayList<HttpHost> httpHosts = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            httpHosts.add(new HttpHost("localhost", 9200 + i));
        }
        HttpHost[] hosts = httpHosts.toArray(new HttpHost[0]);

        CloseableHttpAsyncClient httpClientMock = mock(CloseableHttpAsyncClient.class);
        final ArgumentCaptor<FutureCallback> cbCaptor = ArgumentCaptor.forClass(FutureCallback.class);


        when(httpClientMock.execute(any(HttpAsyncRequestProducer.class), any(HttpAsyncResponseConsumer.class), any(HttpContext.class), cbCaptor.capture()))
            .thenAnswer(new Answer<Future<HttpResponse>>() {
                @Override
                public Future<HttpResponse> answer(InvocationOnMock invocationOnMock) throws Throwable {
                    // this emulates the HTTP client staying on the same thread and not forking the work
                    List<FutureCallback> allValues = cbCaptor.getAllValues();
                    FutureCallback value = allValues.get(allValues.size() - 1);
                    final HttpResponse response = mock(HttpResponse.class);
                    StatusLine statusLine = mock(StatusLine.class);
                    when(response.getStatusLine()).thenReturn(statusLine);
                    when(statusLine.getStatusCode()).thenReturn(502);
                    value.completed(response);

                    return new FutureTask<>(new Callable<HttpResponse>() {
                        @Override
                        public HttpResponse call() throws Exception {
                            return response;
                        }
                    });
                }
            });

        RestClient client = new RestClient(httpClientMock, Long.MAX_VALUE, new Header[]{}, hosts, null, new HostsTrackingFailureListener());
        client.performRequestAsync("GET", "http://localhost:9200", listener);


        listener.get();
    }

@rjernst rjernst added the Team:Data Management Meta label for data/management team label May 4, 2020
@cocodroid
Copy link

how to solve it?

@mattc58
Copy link
Contributor

mattc58 commented Aug 16, 2023

We are closing this for inactivity but will reopen if necessary.

@mattc58 mattc58 closed this as completed Aug 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Clients/Java Low Level REST Client Minimal dependencies Java Client for Elasticsearch Team:Data Management Meta label for data/management team
Projects
None yet
Development

No branches or pull requests