If HttpUriRequest.abort() is called at about the same time that the
request completes, it's possible for an aborted connection to be
returned to the pool.  The next time the connection is used,
HttpClient.execute fails without retrying, throwing this exception:

java.io.IOException: Connection already shutdown
        at
org.apache.http.impl.conn.DefaultClientConnection.opening(DefaultClientC
onnection.java:112)
        at
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection
(DefaultClientConnectionOperator.java:120)
        at
org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:
147)
        at
org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledC
onnAdapter.java:101)
        at
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultReques
tDirector.java:381)
        at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClien
t.java:641)
        at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClien
t.java:576)

Steps to reproduce:
1) Set a breakpoint in ThreadSafeClientConnManager.releaseConnection
just after "reusable" is set (and found to be true).
2) Run to the breakpoint in releaseConnection.
3) Call HttpUriRequest.abort.
4) Let releaseConnection complete.

When the connection is next used, the exception will be thrown.

Snippet from ThreadSafeClientConnManager:
    public void releaseConnection(ManagedClientConnection conn, long
validDuration, TimeUnit timeUnit) {
                ...
            boolean reusable = hca.isMarkedReusable();
            if (log.isDebugEnabled()) {                             //
breakpoint here
                if (reusable) {
                    log.debug("Released connection is reusable.");
                } else {
                    log.debug("Released connection is not reusable.");
                }
            }
            hca.detach();
            if (entry != null) {
                connectionPool.freeEntry(entry, reusable, validDuration,
timeUnit);
            }
        }
    }

I read the contract of ConnectionReleaseTrigger to say that only the
first call of either method has effect so that, for example, a call to
abortConnection made after a call to releaseConnection would be ignored,
but I don't think that's the way AbstractClientConnAdapter is
implemented; I think that it's possible for both methods to have effect.

Am I looking at this correctly?

Thanks for your consideration.

Tim

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

Reply via email to