Skip to content

Connection leak from re-authentication in HttpExecutorServiceImpl.invokeReuqest() #400

@symcssn

Description

@symcssn

UPDATE: Please look at my last comment in this thread from: June 9, 2015

OS4j core/connector: 2.0.4-Snapshot (June 1st)
HttpClient 4.3.6
HttpCore 4.3.3

My application test code kept hanging after a while. I use the default pool sizes. Here is the apache debug log.

... 

2015/06/02 11:24:53:620 PDT [DEBUG] MainClientExec - Executing request HEAD {object URL} HTTP/1.1
2015/06/02 11:24:53:620 PDT [DEBUG] MainClientExec - Target auth state: UNCHALLENGED
2015/06/02 11:24:53:620 PDT [DEBUG] MainClientExec - Proxy auth state: UNCHALLENGED
2015/06/02 11:24:53:620 PDT [DEBUG] headers - http-outgoing-30 >> HEAD {object URL} HTTP/1.1
2015/06/02 11:24:53:620 PDT [DEBUG] headers - http-outgoing-30 >> Accept: application/json; charset=utf-8
2015/06/02 11:24:53:620 PDT [DEBUG] headers - http-outgoing-30 >> X-Auth-Token: {TOKEN}
2015/06/02 11:24:53:620 PDT [DEBUG] headers - http-outgoing-30 >> Host: {host URL}
2015/06/02 11:24:53:620 PDT [DEBUG] headers - http-outgoing-30 >> Connection: Keep-Alive
2015/06/02 11:24:53:620 PDT [DEBUG] headers - http-outgoing-30 >> User-Agent: OpenStack4j-Agent
2015/06/02 11:24:53:620 PDT [DEBUG] headers - http-outgoing-30 >> Accept-Encoding: gzip,deflate
2015/06/02 11:24:53:953 PDT [DEBUG] headers - http-outgoing-30 << HTTP/1.1 200 OK
2015/06/02 11:24:53:953 PDT [DEBUG] headers - http-outgoing-30 << Content-Length: 1
2015/06/02 11:24:53:953 PDT [DEBUG] headers - http-outgoing-30 << Accept-Ranges: bytes
2015/06/02 11:24:53:954 PDT [DEBUG] headers - http-outgoing-30 << Last-Modified: Tue, 02 Jun 2015 18:24:51 GMT
2015/06/02 11:24:53:954 PDT [DEBUG] headers - http-outgoing-30 << Etag: 93b885adfe0da089cdf634904fd59f71
2015/06/02 11:24:53:954 PDT [DEBUG] headers - http-outgoing-30 << X-Timestamp: 1433269490.69728
2015/06/02 11:24:53:954 PDT [DEBUG] headers - http-outgoing-30 << Content-Type: application/octet-stream
2015/06/02 11:24:53:954 PDT [DEBUG] headers - http-outgoing-30 << X-Trans-Id: tx76efdbd5b26d4a38b78a2-00556df4f5
2015/06/02 11:24:53:954 PDT [DEBUG] headers - http-outgoing-30 << Date: Tue, 02 Jun 2015 18:24:53 GMT
2015/06/02 11:24:53:954 PDT [DEBUG] headers - http-outgoing-30 << Connection: close
2015/06/02 11:24:53:954 PDT [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-30: Close connection
2015/06/02 11:24:53:954 PDT [DEBUG] MainClientExec - Connection discarded
2015/06/02 11:24:53:954 PDT [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-30: Close connection
2015/06/02 11:24:53:954 PDT [DEBUG] PoolingHttpClientConnectionManager - Connection released: [id: 30][route: {s}->{route URL:port}][total kept alive: 2; route allocated: 1 of 2; total allocated: 3 of 20]
2015/06/02 11:24:53:955 PDT [DEBUG] RequestAddCookies - CookieSpec selected: best-match
2015/06/02 11:24:53:955 PDT [DEBUG] RequestAuthCache - Auth cache not set in the context
2015/06/02 11:24:53:955 PDT [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: {s}->{route URL:port}][total kept alive: 2; route allocated: 1 of 2; total allocated: 3 of 20]
2015/06/02 11:24:53:955 PDT [DEBUG] PoolingHttpClientConnectionManager - Connection leased: [id: 31][route: {s}->{route URL:port}][total kept alive: 2; route allocated: 2 of 2; total allocated: 4 of 20]
2015/06/02 11:24:53:955 PDT [DEBUG] MainClientExec - Opening connection {s}->{route URL:port}
2015/06/02 11:24:53:955 PDT [DEBUG] HttpClientConnectionOperator - Connecting to {route URL}/{route IP:port}
2015/06/02 11:24:54:157 PDT [DEBUG] HttpClientConnectionOperator - Connection established {source ip:port} <->{dest ip:port}
2015/06/02 11:24:54:157 PDT [DEBUG] MainClientExec - Executing request GET {object URL} HTTP/1.1
2015/06/02 11:24:54:157 PDT [DEBUG] MainClientExec - Target auth state: UNCHALLENGED
2015/06/02 11:24:54:157 PDT [DEBUG] MainClientExec - Proxy auth state: UNCHALLENGED
2015/06/02 11:24:54:157 PDT [DEBUG] headers - http-outgoing-31 >> GET {object URL} HTTP/1.1
2015/06/02 11:24:54:157 PDT [DEBUG] headers - http-outgoing-31 >> Accept: application/json; charset=utf-8
2015/06/02 11:24:54:157 PDT [DEBUG] headers - http-outgoing-31 >> Range: bytes=0-
2015/06/02 11:24:54:157 PDT [DEBUG] headers - http-outgoing-31 >> X-Auth-Token:{TOKEN}
2015/06/02 11:24:54:157 PDT [DEBUG] headers - http-outgoing-31 >> Host: {host URL}
2015/06/02 11:24:54:157 PDT [DEBUG] headers - http-outgoing-31 >> Connection: Keep-Alive
2015/06/02 11:24:54:157 PDT [DEBUG] headers - http-outgoing-31 >> User-Agent: OpenStack4j-Agent
2015/06/02 11:24:54:157 PDT [DEBUG] headers - http-outgoing-31 >> Accept-Encoding: gzip,deflate
2015/06/02 11:24:54:395 PDT [DEBUG] headers - http-outgoing-31 << HTTP/1.1 206 Partial Content
2015/06/02 11:24:54:395 PDT [DEBUG] headers - http-outgoing-31 << Content-Length: 1
2015/06/02 11:24:54:395 PDT [DEBUG] headers - http-outgoing-31 << Accept-Ranges: bytes
2015/06/02 11:24:54:395 PDT [DEBUG] headers - http-outgoing-31 << Last-Modified: Tue, 02 Jun 2015 18:24:51 GMT
2015/06/02 11:24:54:395 PDT [DEBUG] headers - http-outgoing-31 << Content-Range: bytes 0-0/1
2015/06/02 11:24:54:395 PDT [DEBUG] headers - http-outgoing-31 << Etag: 93b885adfe0da089cdf634904fd59f71
2015/06/02 11:24:54:395 PDT [DEBUG] headers - http-outgoing-31 << X-Timestamp: 1433269490.69728
2015/06/02 11:24:54:395 PDT [DEBUG] headers - http-outgoing-31 << Content-Type: application/octet-stream
2015/06/02 11:24:54:396 PDT [DEBUG] headers - http-outgoing-31 << X-Trans-Id: tx2cdb7a2e3da3475491582-00556df4f6
2015/06/02 11:24:54:396 PDT [DEBUG] headers - http-outgoing-31 << Date: Tue, 02 Jun 2015 18:24:54 GMT
2015/06/02 11:24:54:396 PDT [DEBUG] headers - http-outgoing-31 << Connection: close
2015/06/02 11:24:54:397 PDT [DEBUG] RequestAddCookies - CookieSpec selected: best-match
2015/06/02 11:24:54:397 PDT [DEBUG] RequestAuthCache - Auth cache not set in the context
2015/06/02 11:24:54:397 PDT [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: {s}->{route URL:port}][total kept alive: 2; route allocated: 2 of 2; total allocated: 4 of 20]


FREEZING HERE

So I decided to write a simple test application to see if I can reproduce OS4j hanging again. I force synced maven before doing this. Here is the test code:

public class SimpleApp {

    private static OSClient osTenant1;

    private static ObjectStorageService objectStorage;
    private static ObjectStorageAccountService account;
    private static ObjectStorageContainerService containers;
    private static ObjectStorageObjectService objects;

    public SimpleApp() {

        osTenant1 = OSFactory.builder().endpoint(endpoint)
                .credentials(userName, password)
                .tenantName(tenantName).withConfig(config)
                .authenticate();

        objectStorage = osTenant1.objectStorage();
        account = objectStorage.account();
        containers = objectStorage.containers();
        objects = objectStorage.objects();
    }

    public static class RequestThread extends Thread
    {
        private int threadNum;
        private OSClient clientFromAccess;
        private ObjectStorageObjectService objectservice;
        private Access access;

        public RequestThread(int threadNum, Access access)
        {
            this.threadNum = threadNum;
            this.access = access;
        }

        public void run()
        {
            this.clientFromAccess = OSFactory.clientFromAccess(access, config);
            this.objectservice = clientFromAccess.objectStorage().objects();
            makeRequest(threadNum);
        }

        public  void makeRequest(int threadNum)
        {
            System.out.println("Starting requests");
            int requestNumber = 0;
            while (true)
            {
                requestNumber++;
                if (requestNumber % 50 ==0) // I varied this parameter
                {
                    System.out.println("Thread " + threadNum + " making Request #: " + requestNumber);
                }

                objectservice.list("testContainer");

                try {
                    Thread.sleep(50); // I varied this parameter
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }





    public static void main(String[] args) throws FileNotFoundException, InterruptedException {
        try {
            new SimpleApp();

            RequestThread rt1 = new RequestThread(1, osTenant1.getAccess());
            RequestThread rt2 = new RequestThread(2, osTenant1.getAccess());
            RequestThread rt3 = new RequestThread(3, osTenant1.getAccess());

            rt1.start();
            rt2.start();
            rt3.start();

            rt1.join();

        }
    }

}

My test eventually hangs after making requests:

Trial 1:

(200ms sleep, print every 50 requests)
Thread 3 making Request #: 28500
Thread 2 making Request #: 28550
Thread 1 making Request #: 28600

Freezes at this point

Trial 2:

(50ms sleep, print every 50 requests)
Thread 2 making Request #: 49100
Thread 1 making Request #: 48750
Thread 3 making Request #: 49150


Freezes at this point

Trial 3:

(50ms sleep, print every 500 requests)
Thread 1 making Request #: 47500
Thread 2 making Request #: 47500
Thread 3 making Request #: 47500


Freezes at this point

I did a netstat -b while the above test was hung and I see that a connection is established to the swift server.

 [javaw.exe]
  TCP    {ip}:8131       {swift server}:8080          ESTABLISHED
 [javaw.exe]
  TCP    {ip}:8132       {swift server}:8080          ESTABLISHED

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions