[
https://issues.apache.org/jira/browse/HTTPASYNC-81?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Markus Kull updated HTTPASYNC-81:
---------------------------------
Attachment: patch.txt
Thanks a lot for the fast response!
ResponseConsumer is now closed on premature cancel but still not the
RequestProducer. Attached is a patch for trunk which cancels similar to
responseCompleted().
> Callback-Behaviour regarding connection-failures and cancellation during
> transfer.
> -----------------------------------------------------------------------------------
>
> Key: HTTPASYNC-81
> URL: https://issues.apache.org/jira/browse/HTTPASYNC-81
> Project: HttpComponents HttpAsyncClient
> Issue Type: Bug
> Affects Versions: 4.0.1
> Reporter: Markus Kull
> Priority: Minor
> Fix For: 4.0.3, 4.1-alpha1
>
> Attachments: patch.txt
>
>
> The current behaviour regarding the callback-methods in
> HttpAsync-RequestProducer/ResponseConsumer seems surprising to me. I am not
> quite sure wether this is an actual bug or just a misunderstanding by me.
> Some javadocs would be helpful.
> 1) In case of unknown targethost, only close() is called on
> producers+consumers, but not failed() with the exception. Somehow
> inconvenient because the callbacks dont see the result-exception.
> {noformat}
> @Test
> public void testFailedBeforeClose() throws Exception {
> CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
> client.start();
> HttpGet getMethod = new HttpGet("http://doesnotexist.example.org/");
> HttpAsyncRequestProducer producer =
> HttpAsyncMethods.create(getMethod);
> final AtomicBoolean closed = new AtomicBoolean(false);
> final AtomicBoolean cancelled = new AtomicBoolean(false);
> final AtomicBoolean failed = new AtomicBoolean(false);
>
> HttpAsyncResponseConsumer<String> consumer = new
> HttpAsyncResponseConsumer<String>() {
> @Override
> public void close() throws IOException {
> closed.set(true);
> }
> @Override
> public boolean cancel() {
> cancelled.set(true);
> return false;
> }
> @Override
> public void failed(Exception ex) {
> failed.set(true);
> }
>
> public void responseReceived(HttpResponse response) throws
> IOException, HttpException {
> }
> public void consumeContent(ContentDecoder decoder, IOControl
> ioctrl) throws IOException {
> }
> public void responseCompleted(HttpContext context) {
> }
> public Exception getException() {
> return null;
> }
> public String getResult() {
> return "result";
> }
> @Override
> public boolean isDone() {
> return false;
> }
> };
> Future<String> future = client.execute(producer, consumer, null,
> null);
> try {
> future.get();
> Assert.fail();
> } catch (ExecutionException e) {
> Assert.assertTrue(e.getCause() instanceof UnknownHostException);
> }
> Thread.sleep(1000); // give the httpclient time to clean up
>
> Assert.assertTrue(closed.get());
> Assert.assertFalse(cancelled.get());
> Assert.assertTrue(failed.get()); // FAILS! because failed() is not
> called. Seems to be the same for producer
>
> client.close();
> }
> {noformat}
> 2) If the responseconsumer cancels the response (by isDone() returning true
> prematurely), then close() is never called on producers or consumers. This
> could become a resource leak with e.g. ZeroCopyConsumers/Producers.
> Connections seem to be cleaned up, though.
> {noformat}
> @Test
> public void testCloseOnConsumerCancel() throws Exception {
> CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
> client.start();
> HttpGet getMethod = new HttpGet("http://www.example.org/");
> HttpAsyncRequestProducer producer =
> HttpAsyncMethods.create(getMethod);
> final AtomicBoolean closed = new AtomicBoolean(false);
> final AtomicBoolean cancelled = new AtomicBoolean(false);
> final AtomicBoolean failed = new AtomicBoolean(false);
>
> HttpAsyncResponseConsumer<String> consumer = new
> HttpAsyncResponseConsumer<String>() {
> @Override
> public void close() throws IOException {
> closed.set(true);
> }
> @Override
> public boolean cancel() {
> cancelled.set(true);
> return false;
> }
> @Override
> public void failed(Exception ex) {
> failed.set(true);
> }
>
> public void responseReceived(HttpResponse response) throws
> IOException, HttpException {
> }
> public void consumeContent(ContentDecoder decoder, IOControl
> ioctrl) throws IOException {
> }
> public void responseCompleted(HttpContext context) {
> }
> public Exception getException() {
> return null;
> }
> public String getResult() {
> return "result";
> }
> @Override
> public boolean isDone() {
> return true; // cancels fetching the response-body
> }
> };
> Future<String> future = client.execute(producer, consumer, null,
> null);
> future.get();
> Thread.sleep(1000); // give the httpclient time to clean up
> Assert.assertTrue(future.isCancelled());
> // Assert.assertTrue(cancelled.get()); // unclear wether it should be
> set, because the consumer itself cancelled
> Assert.assertFalse(failed.get());
> Assert.assertTrue(closed.get()); // FAILS! the consumer wasnt closed
>
> client.close();
> }
> {noformat}
--
This message was sent by Atlassian JIRA
(v6.2#6252)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]