You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Bronislav Gabrhelik <di...@ahojky.com> on 2013/01/30 13:43:48 UTC

recovery of ther HTTPClient after connection disruption - retrying of the HttpRequest

The original problem I am trying to solve is connection disruption after
resume from the sleep mode (on Windows). When the machine is resumed the
TCP/IP stack is not ready yet, so all requests queued and processed at the
time of rebuilding TCP/IP connectivity are failed. Note that the time
needed for complete recovery in Java is even longer because of DNS caching.
Especially negative TTL has negative impact as it is explicitly set to 10
seconds in java.security, so there is no chance to change it in run-time or
by the system property.

I simulate sleep/resume with disconnecting and connecting of the NIC of the
virtual machine, so I am able to debug problem.

When HttpClient.execute throws some specific exceptions (like
SocketException) we detect that if there are some changes on NIC adapter
configuration and wait for TCP/IP stack recovery (the special JNI was
needed). When conditions are stable we retry to execute  the same
HttpRequest. Note that the HttpRequest is reset by reset() method before
retry.

Unfortunately the execution hangs in AbstractHttpClientConnection.isStale()
for some time like 30 secs (see the stack below). After this problem  I
tried to close the connection with  HttpRequest.abort() to avoid hang, but
I have had no success. Finally the request is failed with
NoHttpResponseException.

How can I recover the HttpClient and/or HttpRequest so I can retry it.

Note that we use some older version of HttpClient - 4.2-alpha +
HttpComponents - 4.1

Thanks in advance,
Bronislav Gabrhelik


---hanging  stack ---

java.net.SocketInputStream.socketRead0

java.net.SocketInputStream.read

org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166)

org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90)

org.apache.http.impl.io.SocketInputBuffer.isDataAvailable(SocketInputBuffer.java:101)

org.apache.http.impl.AbstractHttpClientConnection.isStale(AbstractHttpClientConnection.java:314)

org.apache.http.impl.conn.AbstractClientConnAdapter.isStale(AbstractClientConnAdapter.java:174)

org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:464)

org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:927)

org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:826)

com.xythos.client.drive.remoteprotocol.webdav.WDConnection.executeHttpMethodInternal(WDConnection.java:766)

com.xythos.client.drive.remoteprotocol.webdav.WDConnection.executeHttpMethod(WDConnection.java:712)

com.xythos.client.drive.remoteprotocol.webdav.WDConnection.executeHttpMethod(WDConnection.java:699)

com.xythos.client.drive.remoteprotocol.webdav.WDBasicOperations.updateResource(WDBasicOperations.java:815)

com.xythos.client.drive.remoteprotocol.webdav.WDConnection.updateResource(WDConnection.java:1406)

com.xythos.client.drive.operations.GetAttributesOperation.perform(GetAttributesOperation.java:45)

com.xythos.client.drive.operations.RemoteQueue.perform(RemoteQueue.java:782)

com.xythos.client.drive.operations.OperationQueue.run(OperationQueue.java:263)

java.lang.Thread.run

-- exception thrown---
Caused by: org.apache.http.NoHttpResponseException: The target server
failed to respond
at
org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:108)
at
org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:63)
at
org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
at
org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:285)
at
org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
at
org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:220)
at
org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
at
org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
at
org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:708)
at
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:515)
at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:927)
at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:826)

Re: recovery of ther HTTPClient after connection disruption - retrying of the HttpRequest

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Wed, 2013-01-30 at 13:43 +0100, Bronislav Gabrhelik wrote:
> The original problem I am trying to solve is connection disruption after
> resume from the sleep mode (on Windows). When the machine is resumed the
> TCP/IP stack is not ready yet, so all requests queued and processed at the
> time of rebuilding TCP/IP connectivity are failed. Note that the time
> needed for complete recovery in Java is even longer because of DNS caching.
> Especially negative TTL has negative impact as it is explicitly set to 10
> seconds in java.security, so there is no chance to change it in run-time or
> by the system property.
> 
> I simulate sleep/resume with disconnecting and connecting of the NIC of the
> virtual machine, so I am able to debug problem.
> 
> When HttpClient.execute throws some specific exceptions (like
> SocketException) we detect that if there are some changes on NIC adapter
> configuration and wait for TCP/IP stack recovery (the special JNI was
> needed). When conditions are stable we retry to execute  the same
> HttpRequest. Note that the HttpRequest is reset by reset() method before
> retry.
> 
> Unfortunately the execution hangs in AbstractHttpClientConnection.isStale()
> for some time like 30 secs (see the stack below). After this problem  I
> tried to close the connection with  HttpRequest.abort() to avoid hang, but
> I have had no success. Finally the request is failed with
> NoHttpResponseException.
> 
> How can I recover the HttpClient and/or HttpRequest so I can retry it.
> 
> Note that we use some older version of HttpClient - 4.2-alpha +
> HttpComponents - 4.1
> 

The HttpRequest#abort() interrupts request execution by shutting down
the underlying socket. If socket shutdown does not unblock I/O
operations blocked on it, I would suspect a JRE level issue. Try
upgrading your JRE and see if that makes a difference.

Having said that, since you are using JNI anyway, why not simply
shutting HttpClient down upon a pre-suspend notification?  

Oleg



---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org