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