[ 
https://issues.apache.org/jira/browse/HTTPCLIENT-1958?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Zoe Wang updated HTTPCLIENT-1958:
---------------------------------
    Description: 
When calling HttpRequestBase#abort during the leasing connection phase, the 
thread is being interrupted and `RequestAbortedException` will be thrown.

It is an unexpected behavior that aborting the http request would cause the 
interrupt flag to be set on the caller thread.

Here is what happened looking from the source code of 4.5.5, 
 # Aborting the request invokes future.cancel(true) and it throws 
InterruptedException 
[https://github.com/apache/httpcomponents-client/blob/4.5.5/httpclient/src/main/java/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.java#L272]
 
 # InterruptedException is caught in 
[MainClientExec|https://github.com/apache/httpcomponents-client/blob/4.5.5/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java#L193]
 and then it re-interrupts the thread and throws RequestAbortedException

The second step is expected and the first step seems to be the root cause. 
Should we use `future.cancel(false)` instead as it causes the side effect for a 
simple httprequest#abort to interrupt the caller's thread?

 

Code to reproduce:

ScheduledExecutorService scheduledExecutorService = 
Executors.newScheduledThreadPool(1);

try (
     PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = 
new PoolingHttpClientConnectionManager();
      CloseableHttpClient httpclient = 
HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build())
 {
     

    HttpGet httpGet = new HttpGet("https://somehost.com";);

   // Aborting the request when it's getting a connection from the connection 
pool
      scheduledExecutorService.schedule(httpGet::abort, 40, 
TimeUnit.MILLISECONDS);
      CloseableHttpResponse response = httpclient.execute(httpGet);

      HttpEntity entity = response.getEntity();
      EntityUtils.consume(entity);
   } catch (Exception e) {
       e.printStackTrace();
   } finally {
   scheduledExecutorService.shutdown();
   }

System.out.println("Interrupted ?" + Thread.currentThread().isInterrupted());

 

  was:
When calling HttpRequestBase#abort during the leasing connection phase, the 
thread is being interrupted and `RequestAbortedException` will be thrown.

It is an unexpected behavior that aborting the http request would cause the 
interrupt flag to be set on the caller thread.

Here is what happened looking from the source code of 4.5.5, 
 # Aborting the request invokes future.cancel(true) and it throws 
InterruptedException 
[https://github.com/apache/httpcomponents-client/blob/4.5.5/httpclient/src/main/java/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.java#L272]
 
 # InterruptedException is caught in 
[MainClientExec|https://github.com/apache/httpcomponents-client/blob/4.5.5/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java#L193]
 and then it re-interrupts the thread and throws RequestAbortedException

The second step is expected and the first step seems to be the root cause. 
Should we use `future.cancel(false)` instead as it causes the side effect for a 
simple httprequest#abort to interrupt the caller's thread?

 

Code to reproduce:

{{ScheduledExecutorService scheduledExecutorService = 
Executors.newScheduledThreadPool(1);}}{{try (}}
{{ PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new 
PoolingHttpClientConnectionManager();}}
{{ CloseableHttpClient httpclient =}}
{{ 
HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build())
 {}}
{{ HttpGet httpGet = new HttpGet("https://somehost.com";);}}{{// Aborting the 
request when it's getting a connection from the connection pool}}
{{ scheduledExecutorService.schedule(httpGet::abort, 40, 
TimeUnit.MILLISECONDS);}}
{{ CloseableHttpResponse response = httpclient.execute(httpGet);}}{{HttpEntity 
entity = response.getEntity();}}
{{ EntityUtils.consume(entity);}}
{{ } catch (Exception e) {}}
{{ e.printStackTrace();}}
{{ } finally {}}
{{ scheduledExecutorService.shutdown();}}
{{ }}}

{{System.out.println("Interrupted ?" + 
Thread.currentThread().isInterrupted());}}

 


> Thread interrupt flag leaking when aborting httpRequest during connection 
> leasing stage
> ---------------------------------------------------------------------------------------
>
>                 Key: HTTPCLIENT-1958
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1958
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>          Components: HttpClient (classic)
>    Affects Versions: 4.5.5, 4.5.6
>            Reporter: Zoe Wang
>            Priority: Major
>
> When calling HttpRequestBase#abort during the leasing connection phase, the 
> thread is being interrupted and `RequestAbortedException` will be thrown.
> It is an unexpected behavior that aborting the http request would cause the 
> interrupt flag to be set on the caller thread.
> Here is what happened looking from the source code of 4.5.5, 
>  # Aborting the request invokes future.cancel(true) and it throws 
> InterruptedException 
> [https://github.com/apache/httpcomponents-client/blob/4.5.5/httpclient/src/main/java/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.java#L272]
>  
>  # InterruptedException is caught in 
> [MainClientExec|https://github.com/apache/httpcomponents-client/blob/4.5.5/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java#L193]
>  and then it re-interrupts the thread and throws RequestAbortedException
> The second step is expected and the first step seems to be the root cause. 
> Should we use `future.cancel(false)` instead as it causes the side effect for 
> a simple httprequest#abort to interrupt the caller's thread?
>  
> Code to reproduce:
> ScheduledExecutorService scheduledExecutorService = 
> Executors.newScheduledThreadPool(1);
> try (
>      PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = 
> new PoolingHttpClientConnectionManager();
>       CloseableHttpClient httpclient = 
> HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build())
>  {
>      
>     HttpGet httpGet = new HttpGet("https://somehost.com";);
>    // Aborting the request when it's getting a connection from the connection 
> pool
>       scheduledExecutorService.schedule(httpGet::abort, 40, 
> TimeUnit.MILLISECONDS);
>       CloseableHttpResponse response = httpclient.execute(httpGet);
>       HttpEntity entity = response.getEntity();
>       EntityUtils.consume(entity);
>    } catch (Exception e) {
>        e.printStackTrace();
>    } finally {
>    scheduledExecutorService.shutdown();
>    }
> System.out.println("Interrupted ?" + Thread.currentThread().isInterrupted());
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to