hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Eric Johnson <e...@tibco.com>
Subject Re: RecoverableException -> connection not released from pool?
Date Tue, 22 Apr 2003 13:31:45 GMT

You are undoubtedly correct that better documentation could clarify matters!

In the sense that you "execute" the method, you are allocating something 
yourself.  The contract is something along the lines of "you must make 
sure the connection is released" , after you execute the method.  This 
is not really too tricky, but the need to do so is method and use 
dependent, since different methods and uses may treat the contents of 
the response differently.  You can effect the "release" of the 
connection in a variety of ways:

    * After you call method.getResponseBodyAsStream(), call close on the
      returned InputStream.
    * call method.getResponseBody() or method.getResponseBodyAsString()
    * call method.releaseConnection()

Note that it is usually, if not always benign to call one or more of 
these, although you might need to be prepared for null results.  For 
example, "releaseConnection()" followed by getResponseBody(), or vice 
versa, should both execute just fine, although in the first scenario, 
getResponseBody() ought to return null.

You should definitely NOT call setResponseStream(null) (although perhaps 
you can, I haven't thought about it too hard).  You are precisely 
correct - close on the "response" input stream will release the 
connection to the pool.  When the "close" is called on a response, it is 
a "close" on a wrapper around the underlying socket input stream, not a 
close on the socket input stream itself, and that wrapper triggers the 
correct behavior.  Depending on the response, it may simply release the 
connection and close the socket, or it may consume the remainder of the 
response, so that reusing the connection starts consuming the next 
response from the correct location.

The above works by using the "AutoCloseInputStream", which automatically 
"closes" the stream it is wrapping when it exhausts the data of the 
stream, and it also "notifies" its "watcher" whenever it is closed.  The 
"watcher" in this case is the method that invoked the stream in the 
first place, and when it gets the notification, it releases the 
connection back to the pool.

Unfortunately, there is still more to it than that - it is a subtle 
"dance" that hopefully leads to the expected behavior - except that we 
have to rely on the caller to take the appropriate measure to inform 
HttpClient when the response has been consumed, by using at least one of 
the three choices I listed above.

Jani Mattsson wrote:

>Thanks for your answer. I see. But if this is the way
>it is supposed to work then it should be documented very
>well. Otherwise I tend to assume that I am not responsible
>for releasing something that I didn't explicitly myself allocate 
>in the first place. The way I am using it now the allocation/
>getting of the connection is done behind the scenes by
>HttpClient, so if I don't know about the internals of HttpClient,
>I can't reasonably be expected to know that I need to release
>something if that's not very explicitly stated in bold and blinking
>somewhere in the documentation. Okay this is just a comment from
>an API design point of view, now that I know it I can do it.
>Another thing; I looked at the code for HttpMethodBase.releaseConnection().
>It looks like this (at least in 2003-04-16 version):
>    public void releaseConnection() {
>        if (responseStream != null) {
>            try {
>                // FYI - this may indirectly invoke responseBodyConsumed.
>                responseStream.close();
>            } catch (IOException e) {
>                // attempting cleanup, don't care about exception.
>            }
>        } else {
>            // Make sure the connection has been released. If the response 
>            // stream has not been set, this is the only way to release the 
>            // connection. 
>            ensureConnectionRelease();
>        }
>    }
>So if I did not get it all wrong, in addition to just calling
>releaseConnection() after reading the response from the stream,
>I should also remember to call HttpMethodBase.setResponseStream(null)
>before calling releaseConnection() to make sure my connection really
>is released to the pool - or does this happen somehow automatically
>just by closing the stream as in the above code in some way that I
>am not aware of?
>Best regards,
>Jani Mattsson
>-----Original Message-----
>From: Michael Becke [mailto:becke@u.washington.edu] 
>Sent: 18. huhtikuuta 2003 15:32
>To: Commons HttpClient Project
>Subject: Re: RecoverableException -> connection not released from pool?
>HttpMethod.releaseConnection() should always be called, regardless of 
>if an exception occurs or not.  This method is not automatically called 
>by HttpClient or by the method since a connection cannot be released 
>until it is no longer going to be used.  For example, when performing a 
>GET the connection is not just used to post the request but also to 
>read the response.  Since the response is to be handled by the user 
>code HttpClient cannot determine on it's own when the connection is no 
>longer in use.  In reality, connection release is handled automatically 
>for some cases, but it is better to be absolutely sure by calling 
>releaseConnection() (especially when using 
>On Friday, April 18, 2003, at 03:34 AM, Jani Mattsson wrote:
>>No I am actually calling HttpClient.executeMethod(). But I don't see 
>>any difference, because at least in the 20030416 nightly drop the last 
>>line of code in HttpClient.executeMethod() is "return 
>>method.execute(state, connection)"
>>without any enclosing try-finally blocks. Therefore as far as I 
>>there's no difference in this respect whether calling the method 
>>or through HttpClient.
>>But in any case it feels a little strange that I have to do the
>>couldn't the httpclient do that before returning to my calling method?
>>-----Original Message-----
>>From: Aurelien Pernoud [mailto:apernoud@sopragroup.com]
>>Sent: 17. huhtikuuta 2003 11:43
>>To: 'Commons HttpClient Project'
>>Subject: RE: RecoverableException -> connection not released from 
>>You have to call httpmethodbase.releaseconnection() in the finally()
>>of your try/catch, if not using httpclient but method directly (which I
>>think you are), otherwise it doesn't get released. Sample :
>>GetMethod method = new GetMethod();
>>// add whatever you want to this method
>>    method.execute(aState, aConnection);
>>catch (Exception e)
>>	//Handle exception
>>    method.releaseConnection();
>>Jani Mattsson a écrit :
>>>I'm experiencing problems using HttpClient with 
>>>for connections over HTTPS. For one reason or another I get 
>>>HttpRecoverableExceptions when executing the methods, and I have code 
>>>to retry a number of times after such an exception. Now it seems that 
>>>in case a HttpRecoverableException is thrown,
>>>HttpMethodBase.execute() never releases the connection back to the 
>>>connection manager. Thus when I have a quota of four connections per 
>>>host, after HttpRecoverableException my HttpClient sits in deadlock 
>>>waiting for someone to release a connection, in vain.
>>>Is this a known problem, or am I perhaps doing something wrong in the 
>>>way I retry / handle the case when the recoverableexceptions are 
>>>Best regards,
>>>Jani Mattsson
>>This message has been scanned by F-Secure Anti-Virus for Microsoft
>>For more information, connect to http://www.F-Secure.com/
>>To unsubscribe, e-mail:
>>For additional commands, e-mail: 
>This message has been scanned by F-Secure Anti-Virus for Microsoft Exchange.
>For more information, connect to http://www.F-Secure.com/
>To unsubscribe, e-mail: commons-httpclient-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-httpclient-dev-help@jakarta.apache.org

View raw message