[ 
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]

Reply via email to