javaShilp
javaShilp

Reputation: 59

Apache HTTP Client - Issues with 0 leased connections in Apache Http client

I am trying to use PoolingHttpClientConnectionManager in our module.

Below is my code snippet

import java.io.IOException;
import org.apache.hc.client5.http.ClientProtocolException;
import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.io.entity.EntityUtils;

public class Testme {
    static PoolingHttpClientConnectionManager connectionManager;
    static CloseableHttpClient httpClient;

    public static void main(String args[]) {
        connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setDefaultMaxPerRoute(3);
        connectionManager.setMaxPerRoute(new HttpRoute(new HttpHost("http://127.0.0.1",8887)), 5);
        httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager).build();
        System.out.println("Available connections "+connectionManager.getTotalStats().getAvailable());
        System.out.println("Max Connections "+connectionManager.getTotalStats().getMax());
        System.out.println("Number of routes "+connectionManager.getRoutes().size());
        Testme testme = new Testme();
        Testme.ThreadMe threads[] = new Testme.ThreadMe[5];
        for(int i=0;i<5;i++) 
            threads[i] = testme.new ThreadMe();

        for(Testme.ThreadMe thread:threads) { 
            System.out.println("Leased connections before assigning "+connectionManager.getTotalStats().getLeased());
            thread.start(); 
        }
    }

    class ThreadMe extends Thread{

        @Override
        public void run() {
            try {
                CloseableHttpResponse response= httpClient.execute(new HttpGet("http://127.0.0.1:8887"));
                System.out.println("Req for "+Thread.currentThread().getName() + " executed with "+response);
                try {
                    HttpEntity entity = response.getEntity();
                    EntityUtils.consume(entity);
                }catch(IOException e) {
                    e.printStackTrace();    
                }
                finally {   
                    response.close();
                } 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

the output i received was as below:

Available connections 0
Max Connections 25
Number of routes 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Req for Thread-2 executed with 200 OK HTTP/1.1
Req for Thread-4 executed with 200 OK HTTP/1.1
Req for Thread-3 executed with 200 OK HTTP/1.1
Req for Thread-0 executed with 200 OK HTTP/1.1
Req for Thread-1 executed with 200 OK HTTP/1.1

I am unable to find my leased connections are always 0 though there are requests executing. Also, the routes are always shown as 0 though I have registered the route. It seems to me that there is some problem but I could not identify it. Available connections are also shown as 0 during execution(though it is not printed here). Please help me in finding out what went wrong. Thanks!

Upvotes: 0

Views: 2489

Answers (1)

YevgenyL
YevgenyL

Reputation: 331

The first print of "Available connections" message is of course 0, as only after you'll get the response and it'll be decided, based on default strategies DefaultClientConnectionReuseStrategy & DefaultConnectionKeepAliveStrategy, if the connection should be reusable, and for how long, only then the connection will be moved to available connections list.

I'm guessing that the number of routes is also decided after at least one connection was created.

In your log you can see that the main thread printed all the "Leased connections before assigning" messages before the child threads ran, and so you see 0 leased connections. A connection exists in leased connections list only from the time of creation until the releasing time, that usually happens on response.readEntity(), response.close(), the closing of the connection manager, and maybe on EntityUtils.consume() as well.

So maybe try to move the "Leased connections before assigning" from the main thread to child thread.

Upvotes: 1

Related Questions