On May 11, 2010, at 11:53am, Brooks, Kenneth S wrote:

In the 4.0.1 tutorial I see the following paragraph.

... begin snippet ...
HttpClient tries to mitigate the problem by testing whether the connection is 'stale', that is no longer valid because it was closed on the server side, prior to using the connection for executing an HTTP request. The stale connection check is not 100% reliable and adds 10 to 30 ms overhead to each request execution. The only feasible solution that does not involve a one thread per socket model for idle connections is a dedicated monitor thread used to evict connections that are considered expired due to a long period of inactivity. The monitor thread can periodically call ClientConnectionManager#closeExpiredConnections() method to close all expired connections and evict closed connections from the pool. It can also optionally call ClientConnectionManager#closeIdleConnections() method to close all connections that have been idle over a given period of time.
... end snippet ...

Today we implement both the stale connection checking as well as the IdleConnectionTimeoutThread (in 3.1). I would love to save the 10-30ms overhead but without doing that stale check it is possible that a connection was closed (that the Idle monitor may not have awoken to catch).. Sounds like to me the only way to be as close to 100% safe is to implement both..

Is that correct?

I don't believe so.

Assuming the connection is stale, then you'll get an exception when you try to use it, so assuming you have a retry handler installed, you can automatically retry that type of failure.

Some code from the Bixo project to illustrate:

            _httpClient = new DefaultHttpClient(cm, params);
_httpClient.setHttpRequestRetryHandler(new MyRequestRetryHandler(MAX_RETRY_COUNT));


private static class MyRequestRetryHandler implements HttpRequestRetryHandler {
        private int _maxRetryCount;

        public MyRequestRetryHandler(int maxRetryCount) {
            _maxRetryCount = maxRetryCount;
        }

        @Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
            if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Decide about retry #" + executionCount + " for exception " + exception.getMessage());
            }

            if (executionCount >= _maxRetryCount) {
                // Do not retry if over max retry count
                return false;
            } else if (exception instanceof NoHttpResponseException) {
                // Retry if the server dropped connection on us
                return true;
            } else if (exception instanceof SSLHandshakeException) {
                // Do not retry on SSL handshake exception
                return false;
            }

HttpRequest request = (HttpRequest)context.getAttribute(ExecutionContext.HTTP_REQUEST); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
            // Retry if the request is considered idempotent
            return idempotent;
        }
    }


--------------------------------------------
Ken Krugler
+1 530-210-6378
http://bixolabs.com
e l a s t i c   w e b   m i n i n g




Reply via email to