[
https://issues.apache.org/jira/browse/HTTPASYNC-54?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13767773#comment-13767773
]
Oleg Kalnichevski commented on HTTPASYNC-54:
--------------------------------------------
Ben,
I ran this application (see source below) that basically executed 200'000 GET
requests synchronously against local Tomcat instance. The total execution time
was a bit over a minute. I would say this looks all right. So, if there is a
defect it must be triggered by something more than just synchronous execution.
{code}
package org.apache.http.examples.nio.client;
import org.apache.http.HttpResponse;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.methods.AsyncByteConsumer;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncMethods;
import org.apache.http.protocol.HttpContext;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.concurrent.Future;
public class AsyncClientHttpBlocking {
public static void main(final String[] args) throws Exception {
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
httpclient.start();
try {
long start = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
Future<Boolean> future = httpclient.execute(
HttpAsyncMethods.createGet("http://localhost:8080/"),
new MyResponseConsumer(), null);
Boolean result = future.get();
if (!result) {
System.out.println("Request failed");
}
}
long end = System.currentTimeMillis();
System.out.println("Total time (sec):" + ((double)(end - start)) /
1000);
} finally {
httpclient.close();
}
System.out.println("Done");
}
static class MyResponseConsumer extends AsyncByteConsumer<Boolean> {
@Override
protected void onResponseReceived(final HttpResponse response) {
}
@Override
protected void onByteReceived(
final ByteBuffer buf,
final IOControl ioctrl) throws IOException {
}
@Override
protected void releaseResources() {
}
@Override
protected Boolean buildResult(final HttpContext context) {
return Boolean.TRUE;
}
}
}
{code}
{noformat}
Total time (sec):77.722
Done
Process finished with exit code 0
{noformat}
Oleg
> 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]