Hi Oleg,

Below is a program that reproduces the hang. It might take a couple of runs to make this happen - it depends on what thread the callback is generated on. If it's on the IO Dispatcher thread, we can close the connection on that thread also and there's no problem. If the callback comes on the pool-thread the program hangs. The stack trace of the pool-thread when this happens looks like this:

Thread [pool-1-thread] (Suspended) <-- I paused it in the debugger but this is where it stays
  owns: SessionRequestImpl (id=44)
  waiting for: Thread (id=21)
  Object.wait(long)
   Thread.join(long)
   Thread.join()
   InternalHttpAsyncClient(ClosableHttpAsyncClientBase).close()
   Testprog$Callback.failed(Exception)
etc.

Here's the example program:

package httptest;


import java.util.concurrent.CountDownLatch;


import org.apache.http.HttpResponse;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.concurrent.FutureCallback;

import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;

import org.apache.http.impl.nio.client.HttpAsyncClients;


public class Testprog {

public void run() throws Exception

{

Thread t = Thread.currentThread();

System.out.println(t.getName() + ": " + "Start of test program");


CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();

try {

httpclient.start();


try {

CountDownLatch latch = new CountDownLatch(1);

finalHttpGet request= newHttpGet("https://www.redpt.com/api/versions/";);

Callback cb = new Callback(httpclient, request, latch);

httpclient.execute(request, cb);

System.out.println(t.getName() + ": " + "Waiting for requests to complete");

latch.await();

System.out.println(t.getName() + ": " + "Requests are complete");

} catch (Exception ex) {

System.out.println(t.getName() + ": " + ex.getMessage());

}


} finally{

//httpclient.close();   <--  This works if it's done here

}


System.out.println(t.getName() + ": " + "End of test program");

}


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


Testprog prog = new Testprog();

prog.run();

}

private class Callback implements FutureCallback<HttpResponse>

{

CloseableHttpAsyncClient _httpclient;

HttpGet _request;

CountDownLatch _latch;

public Callback(CloseableHttpAsyncClient httpclient, HttpGet request, CountDownLatch latch)

{

_httpclient= httpclient;

_request= request;

_latch = latch;

}

@Override

public void cancelled() {

Thread t = Thread.currentThread();

System.out.println(t.getName() + ": " + "Request cancelled");

try {

System.out.println(t.getName() + ": " + "Closing client connection");

_httpclient.close();

} catch (Exception ex) {

System.out.println(t.getName() + ": " + ex.getMessage());

}

_latch.countDown();

}


@Override

public void completed(HttpResponse response) {

Thread t = Thread.currentThread();

System.out.println(t.getName() + ": " + "Request completed");

System.out.println(t.getName() + ": " + _request.getRequestLine()+ " -> " + response.getStatusLine());

try {

System.out.println(t.getName() + ": " + "Closing client connection");

_httpclient.close();

} catch (Exception ex) {

System.out.println(t.getName() + ": " + ex.getMessage());

}

_latch.countDown();

}


@Override

public void failed(Exception ex) {

Thread t = Thread.currentThread();

System.out.println(t.getName() + ": " + "Request failed");

System.out.println(t.getName() + ": " + _request.getRequestLine() + " -> " + ex.getMessage());

try {

System.out.println(t.getName() + ": " + "Closing client connection");

_httpclient.close();

} catch (Exception ex1) {

System.out.println(t.getName() + ": " + ex1.getMessage());

}

_latch.countDown();

}

}


}


Looks like my formatting got messed up.

Thanks again,
Mark



On 1/26/2016 12:31 PM, Oleg Kalnichevski wrote:
On January 26, 2016 6:01:59 PM GMT+01:00, Mark Johnson <mjohnson...@gmail.com> 
wrote:
Hi,

We're still trying to put together a concise example but have
determined
some information and a work-around.  Here's the scenario that happens:

Thread:
Start-up :    Creates the Http connection;  This starts an IO
Dispatcher
3 thread and a pool-41-thread-1 (for example).  The Http request is now

issued

pool-41-thread-1:  Gets the error (timeout or connection closed by
peer).  This Http request is retried
pool-41-thread-1:  Gets the error again; The operation is retried
again.
pool-41-thread-1:  Gets the error again;  The connection is closed
(hangs here)

Hi Mark
What does 'hangs here' mean exactly? Blocked on a mutex? Running in a tight 
loop? Something else?

Is your application using plain HTTP or HTTPS?

Oleg


Reply via email to