0

For some reason HttpAsyncClient isn't making request if setConnectionManagerShared is set to true. I found this bug but couldn't figure out what I'm missing.

Here is how I create new client

def apply(proxy: Option[HttpHost], cookieStore: Option[CookieStore]) = {

val builder = HttpAsyncClients.custom.
  setConnectionManager(connManager).
  setConnectionManagerShared(true).
  setDefaultCredentialsProvider(credentialsProvider).
  setDefaultRequestConfig(defaultRequestConfig).
  setSSLStrategy(sslStrategy)

proxy.map(builder.setProxy)
builder.setDefaultCookieStore(cookieStore.getOrElse(new BasicCookieStore)) // Use custom cookie store if necessary.

// Create an HttpClient with the given custom dependencies and configuration.
val client: HttpAsyncClient = new HttpAsyncClient(builder.build)
client
}

Full class is located is here.

What should I change ?

expert
  • 29,290
  • 30
  • 110
  • 214

1 Answers1

1
DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);

CloseableHttpAsyncClient client1 = HttpAsyncClients.custom()
        .setConnectionManager(cm)
        .build();
CloseableHttpAsyncClient client2 = HttpAsyncClients.custom()
        .setConnectionManager(cm)
        .setConnectionManagerShared(true)
        .build();

client1.start();
client2.start();

final CountDownLatch latch = new CountDownLatch(2);
FutureCallback callback = new FutureCallback<HttpResponse>() {
    @Override
    public void completed(HttpResponse result) {
        latch.countDown();
        System.out.println(result.getStatusLine());
    }

    @Override
    public void failed(Exception ex) {
        latch.countDown();
        System.out.println(ex.getMessage());
    }

    @Override
    public void cancelled() {
        latch.countDown();
    }
};

client1.execute(new HttpGet("http://httpbin.org/get"), callback);
client2.execute(new HttpGet("http://httpbin.org/get"), callback);
latch.await();

// I am aware this is sloppy
client1.close();
client2.close();
ok2c
  • 26,450
  • 5
  • 63
  • 71
  • Thank you! Is it possible that it's not working because I call `setConnectionManagerShared` for every created client ? And if yes does it mean I need to "owning" client non-closed? – expert Sep 08 '15 at 08:38
  • There should be a service responsible for starting up and shutting down the underlying the I/O reactor. It is easier to accomplish by one client 'owning' the connection manager, but also can be done completely independently. – ok2c Sep 08 '15 at 09:13
  • Got it. I'll keep one dummy client in my singleton then. It seems bit hackish to me though. – expert Sep 08 '15 at 09:17
  • As I said you do not need to do so. You can also maintain an instance of IOReactor and control its life cycle in your singleton. – ok2c Sep 08 '15 at 09:54
  • You will effectively have to duplicate most of this code http://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/xref/org/apache/http/impl/nio/client/CloseableHttpAsyncClientBase.html#40 – ok2c Sep 08 '15 at 10:01
  • What should I use as `IOEventDispatch` ? `InternalIODispatch` is package only class. – expert Sep 21 '15 at 14:16
  • You can use DefaultHttpClientIODispatch or extend AbstractIODispatch – ok2c Sep 22 '15 at 08:10