[ 
https://issues.apache.org/jira/browse/HTTPCLIENT-2142?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17303617#comment-17303617
 ] 

Carter Kozak commented on HTTPCLIENT-2142:
------------------------------------------

> Question: Why is it not possible to use use background thread which does a 
>"validate while idle" (whatever idle means)?

That's a good idea, it could work similarly to the IdleConnectionEvictor. We 
would still be limited to 1ms per connection per thread, and the longer a 
connection sits idle the higher the probability that it's closed by the remote 
server between a stale check and a request, but I think it would solve the 
problem in which a server bounces and all retries are exhausted, and that's my 
primary goal.

> Idea: mod_proxy_http uses HTTP 100-Continue for a ping. See 
>[{{ProxyPass}}|https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypass] 
>directive. Would that be a way to solve the problem?

I like this idea, I think we would need to bound the latency of the continue 
response because in the worst case it could take much longer than the current 
check. We would need to allow this request to fail due to I/O issues (perhaps 
with the exception of a read timeout waiting for the continue response) in a 
way that doesn't exhaust retries as well. Not all servers support 100-Continue, 
so this may not be a general-purpose solution.

> Design expressive idle connection validation support
> ----------------------------------------------------
>
>                 Key: HTTPCLIENT-2142
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-2142
>             Project: HttpComponents HttpClient
>          Issue Type: New Feature
>            Reporter: Carter Kozak
>            Assignee: Carter Kozak
>            Priority: Major
>
> This ticket is based on a discussion from the mailing list: 
> http://mail-archives.apache.org/mod_mbox/hc-dev/202103.mbox/%3C60fa1a2bad046869a2da9269b7e90b9484a050ca.camel%40apache.org%3E
> h3. Background
> Currently several connection managers support a validation interval for idle 
> connections which is used to check if they're still open before attempting to 
> send a request. The java Socket API provides no way for a client to detect if 
> the remote side has closed a connection without attempting a blocking read 
> operation. In my experience the most common failure is that a remote server 
> _cleanly_ closes idle connections sooner than the client expects (either due 
> to a low idle connection timeout or a server shutdown) resulting in failed 
> requests and retries.
> A stale check on a java socket takes at minimum 1 millisecond due to the 
> millisecond socket timeout resolution, and the only way (that I'm aware of) 
> to check if a connection has been closed is to do a blocking read. A 
> SocketTimeoutException tells us the connection is intact, while other 
> IOExceptions suggest the connection is unusable. In many environments a 1ms 
> check is far more expensive than the median request to a remote server and 
> causes additional context switching.
> When the validation interval is set to a higher value to avoid performance 
> pitfalls, idle connections may build up in the connection pool. If the remote 
> server unexpectedly restarts, the client may need to churn through hundreds 
> of requests burning through retries before the higher validation interval is 
> reached or remaining connections are closed due to reaching the keepalive 
> timeout.
> h3. Potential Ideas
> h4. Route state awareness
> Track connection health state per route such that stale checks are required 
> before using a connection that has been idle longer than any connection that 
> has been determined to be stale. This requires functionality to detect 
> {{ConnectionClosedException}} and {{NoHttpResponseException}} produced by 
> attempted requests, and send it back to the connection pool. This allows 
> retryable requests to be executed optimistically (in cases where it's safe to 
> do so) and only pre-validate after a failure has occurred to limit the number 
> of retries that may be consumed.
> h4. Request-aware stale checking predicate
> Provide a configurable mechanism to force stale checks based on the incoming 
> request, for example I may always want to validate connections before making 
> requests to non-idempotent endpoints or when by request body is not 
> considered repeatable, but have more risk tolerance when I'm confident a 
> retry is possible. Perhaps also force stale connection checks for all 
> retries. 
> h4. Alternative forms of stale checks
> We may consider making the stale-check mechanism itself configurable, a 
> blocking read to be used, or an http2 ping when available, or even a full 
> {{OPTIONS}} or {{HEAD}} request.
> It's not entirely clear if any of this should be shared between the classic 
> and async clients. I think the nio interfaces provide support for the common 
> case (cleanly closed connections) which is a deficiency of the blocking 
> socket API.
> What do you think? Additional ideas are appreciated.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

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

Reply via email to