[
https://issues.apache.org/jira/browse/HTTPASYNC-54?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ben Christensen resolved HTTPASYNC-54.
--------------------------------------
Resolution: Not A Problem
Resolving as it is not the code but JDK 1.7.0_05
> AsyncClient.execute hangs (or extremely slow) if Future.get is invoked
> between requests
> ---------------------------------------------------------------------------------------
>
> Key: HTTPASYNC-54
> URL: https://issues.apache.org/jira/browse/HTTPASYNC-54
> Project: HttpComponents HttpAsyncClient
> Issue Type: Bug
> Affects Versions: 4.0-beta4
> Environment: $ java -version
> java version "1.7.0_40"
> Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
> Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)
> $ uname -a
> Darwin lgmac-bchristensen 12.5.0 Darwin Kernel Version 12.5.0: Mon Jul 29
> 16:33:49 PDT 2013; root:xnu-2050.48.11~1/RELEASE_X86_64 x86_64
> Reporter: Ben Christensen
>
> When executing requests in a loop, if the returned Future<HttpResponse> is
> dereferenced by calling get() it is expected it will cause the loop to happen
> sequentially, each request happening one at a time.
> Pseudo code (this approach does not work):
> for 1...5
> Future f = asyncHttpClient.execute()
> f.get()
>
> What actually happens is it seems to hang, or at best start taking several
> minutes per requests as opposed to milliseconds.
> If the for-loop of requests is done completely asynchronously and the Futures
> just collected and dereferenced after all requests are executed, then it
> works fine.
> Pseudo code (this approach works):
> for 1...5
> listOfFutures << asyncHttpClient.execute()
> for f in listOfFutures
> f.get()
> I intend on a completely non-blocking strategy, but there are times when
> blocking is needed, and many will use my library in that manner, so I need
> this to work.
> Either I'm doing something very wrong, or there is indeed an issue. No amount
> of breakpoints or debugging has led me yet to where the issue is, so sorry
> that all I can do is provide an example of the problem and not a pointer to
> what I think the solution is.
> Thank you in advance for your time on this matter.
> Following is code that demonstrates the issue and log output of the scenarios:
> ----------------------------------------------------------
> Code demonstrating issue:
> ----------------------------------------------------------
> import java.util.concurrent.Future;
> 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;
> import org.apache.http.protocol.BasicHttpContext;
> public class TestAynscHttpClient {
> public static void main(String args[]) {
> CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
> client.start();
> try {
> /*
> * This should execute 5 requests asynchronously and receive
> responses in the FutureCallback handler.
> *
> * If the `f.get()` line is invoked, only the first will work, no
> further requests will execute
> * (or sometimes if I leave it sitting for minutes I see a second
> request go through).
> *
> * If the `f.get()` line is commented out, then all 5 correctly
> execute and return.
> *
> * It is expected that if someone calls `f.get()` in this loop it
> should cause the requests
> * to happen sequentially, but they should still work.
> */
> for (int i = 0; i < 5; i++) {
> System.out.println("execute request");
> Future<HttpResponse> f = client.execute(new
> HttpGet("http://www.google.com"),
> new BasicHttpContext(), new
> FutureCallback<HttpResponse>() {
> @Override
> public void failed(Exception ex) {
> System.out.println("failed");
> }
> @Override
> public void completed(HttpResponse result) {
> System.out.println("Result: " + result);
> }
> @Override
> public void cancelled() {
> System.out.println("cancelled");
> }
> });
> try {
> f.get();// commenting out this line makes the 5 requests
> succeed
> } catch (Exception e) {
> e.printStackTrace();
> }
> System.out.println("after f.get()");
> }
> // wait for all async tasks to complete (when f.get is commented
> out)
> } finally {
> try {
> Thread.sleep(2000);
> client.close();
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
> }
> }
> ----------------------------------------------------------
> Here is output with f.get() disabled:
> ----------------------------------------------------------
>
> execute request
> after f.get()
> execute request
> after f.get()
> execute request
> after f.get()
> execute request
> after f.get()
> execute request
> after f.get()
> Result: HTTP/1.1 200 OK [Date: Sun, 15 Sep 2013 03:45:00 GMT, Expire...
> cropped for brevity
> Result: HTTP/1.1 200 OK [Date: Sun, 15 Sep 2013 03:45:00 GMT, Expire...
> cropped for brevity
> Result: HTTP/1.1 200 OK [Date: Sun, 15 Sep 2013 03:45:00 GMT, Expire...
> cropped for brevity
> Result: HTTP/1.1 200 OK [Date: Sun, 15 Sep 2013 03:45:00 GMT, Expire...
> cropped for brevity
> Result: HTTP/1.1 200 OK [Date: Sun, 15 Sep 2013 03:45:00 GMT, Expire...
> cropped for brevity
>
> ----------------------------------------------------------
> Here is output with f.get() enabled:
> ----------------------------------------------------------
> execute request
> after f.get()
> execute request
> Result: HTTP/1.1 200 OK [Date: Sun, 15 Sep 2013 03:43:47 GMT, Expire...
> cropped for brevity
> ----------------------------------------------------------
> Here is output with f.get() enabled and letting it run
> for several minutes. Note several minutes between responses.
> ----------------------------------------------------------
>
> execute request
> after f.get()
> execute request
> Result: HTTP/1.1 200 OK [Date: Sun, 15 Sep 2013 03:38:59 GMT, Expire...
> cropped for brevity
> after f.get()
> execute request
> Result: HTTP/1.1 200 OK [Date: Sun, 15 Sep 2013 03:42:59 GMT, Expire...
> cropped for brevity
> ----------------------------------------------------------
> This code also hangs on the second request:
> ----------------------------------------------------------
> try {
> client.execute(new HttpGet("http://www.google.com"),
> new BasicHttpContext(), new
> FutureCallback<HttpResponse>() {
> @Override
> public void failed(Exception ex) {
> System.out.println("failed");
> }
> @Override
> public void completed(HttpResponse result) {
> System.out.println("Result: " + result);
> }
> @Override
> public void cancelled() {
> System.out.println("cancelled");
> }
> }).get();
>
> client.execute(new HttpGet("http://www.apple.com"),
> new BasicHttpContext(), new
> FutureCallback<HttpResponse>() {
> @Override
> public void failed(Exception ex) {
> System.out.println("failed");
> }
> @Override
> public void completed(HttpResponse result) {
> System.out.println("Result: " + result);
> }
> @Override
> public void cancelled() {
> System.out.println("cancelled");
> }
> }).get();
> } catch (Exception e1) {
> e1.printStackTrace();
> }
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]