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 Stevo Slavić <ss...@gmail.com> on 2011/01/11 06:11:08 UTC

HttpDelete and similar could exhaust your http connection pool if not handled properly

Hello httpclient-users,

Beginner httpclient user here and this is more note to self and
httpclient users alike. Been hit by http connection pool getting
exhausted, randomly, on production... For few days I've been BMHATW,
suspected even that it's a bug in httpclient 4.0.x, switched to latest
4.1-beta2-SNAPSHOT which btw works ok for me. With extra logging on
client and server side of communication I've found out that delete
requests didn't return connection back to the pool. After RTFM on
releasing low level resources (see [1]), I've added try-finally around
client.execute(httpDelete) and aborting of httpDelete in finally, and
ta-da, connections would get returned to the pool.

Regards,
Stevo.

[1] "1.1.5. Ensuring release of low level resources"

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html#d4e143

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


Re: HttpDelete and similar could exhaust your http connection pool if not handled properly

Posted by Stevo Slavić <ss...@gmail.com>.
Thanks guys, learned a lot!

Regards,
Stevo.

On Tue, Jan 11, 2011 at 11:18 PM, sebb <se...@gmail.com> wrote:
> On 11 January 2011 21:21, Stevo Slavić <ss...@gmail.com> wrote:
>> @sebb
>>
>> 1) it's "delete" - tried to copy multiple fragments and assemble brief
>> readable one for the mail, made error, but I hope we understood each
>> other.
>
> I was just checking.
>
>> 2) delete can be null, HttpClient.execute(HttpUriRequest request)
>> doesn't state request is final, so it can point to anything after
>> being passed to execute
>
> No, Java does not work like that.
>
> Variables are passed by value; a called method can only change the
> referenced object, not the value of the variable.
>
> Declaring a parameter as final just means that the parameter value
> cannot be changed within the method.
> The referenced object can still be updated if it is mutable.
>
>> 3) please don't waste time documenting to be deprecated api
>>
>
> As it happens, the documentation has already been updated.
>
>> @Oleg
>>
>> 4) So it's better / more recommended to consumeContent of response
>> entity than to abort request? Is connection considered reusable when
>> contentConsumed compared to abort where it gets discarded and new
>> connection needs to be instantiated?
>>
>> 5) I see in 4.1(-beta2-SNAPSHOT) HttpClient.consumeContent is
>> deprecated in favor of EntityUtils.consume - there it just gets
>> content stream reference and closes it so its performance is let say
>> constant - not affected by content size. I think I read, before 4.1,
>> abort was more favorable than consumeContent in cases of large
>> response content streams.
>>
>> 6) What if client.execute throws exception and it's not handled (so
>> neither response content is consumed nor request aborted), will
>> connection be returned to the pool, discarded as invalid, or trapped
>> eternally exhausting the pool?
>>
>>
>>
>> Regards,
>> Stevo
>>
>> On Tue, Jan 11, 2011 at 9:19 PM, Oleg Kalnichevski <ol...@apache.org> wrote:
>>> On Tue, 2011-01-11 at 19:17 +0100, Stevo Slavić wrote:
>>>> It seems they were.
>>>>
>>>> On client side of communication I now have:
>>>>
>>>>
>>>>               HttpDelete httpDelete = new HttpDelete(deleteUrl);
>>>>
>>>>               try {
>>>>                       HttpResponse response = client.execute(delete);
>>>>                       if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
>>>>                               throw new SomeCustomException(response.getStatusLine().getStatusCode(),
>>>> response.getStatusLine().getReasonPhrase());
>>>>                       }
>>>>               } catch (IOException ioe) {
>>>>                       throw new SomeCustomException(ioe);
>>>>               } finally {
>>>>                       if (delete != null) {
>>>>                               delete.abort();
>>>>                       }
>>>>               }
>>>>
>>>>
>>>> Without finally and abort call in it (also with abort just on
>>>> IOException in catch block), connections would not get returned to the
>>>> pool in regular non-exceptional return. HttpDelete refrence is lost -
>>>> not accessible outside of this block/method. This puts responsibility
>>>> to the developer to clean up low level resources which weren't
>>>> directly created or accessed - I guess it has to be like that.
>>>>
>>>
>>> What is wrong with just this?
>>>
>>> HttpDelete httpDelete = new HttpDelete(deleteUrl);
>>> HttpResponse response = client.execute(httpDelete);
>>> HttpEntity entity = response.getEntity();
>>> if (entity != null) {
>>>    entity.consumeContent();
>>> }
>>> if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
>>>   throw new SomeCustomException();
>>> }
>>>
>>> Oleg
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
>>> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
>> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>
>

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


Re: HttpDelete and similar could exhaust your http connection pool if not handled properly

Posted by sebb <se...@gmail.com>.
On 11 January 2011 21:21, Stevo Slavić <ss...@gmail.com> wrote:
> @sebb
>
> 1) it's "delete" - tried to copy multiple fragments and assemble brief
> readable one for the mail, made error, but I hope we understood each
> other.

I was just checking.

> 2) delete can be null, HttpClient.execute(HttpUriRequest request)
> doesn't state request is final, so it can point to anything after
> being passed to execute

No, Java does not work like that.

Variables are passed by value; a called method can only change the
referenced object, not the value of the variable.

Declaring a parameter as final just means that the parameter value
cannot be changed within the method.
The referenced object can still be updated if it is mutable.

> 3) please don't waste time documenting to be deprecated api
>

As it happens, the documentation has already been updated.

> @Oleg
>
> 4) So it's better / more recommended to consumeContent of response
> entity than to abort request? Is connection considered reusable when
> contentConsumed compared to abort where it gets discarded and new
> connection needs to be instantiated?
>
> 5) I see in 4.1(-beta2-SNAPSHOT) HttpClient.consumeContent is
> deprecated in favor of EntityUtils.consume - there it just gets
> content stream reference and closes it so its performance is let say
> constant - not affected by content size. I think I read, before 4.1,
> abort was more favorable than consumeContent in cases of large
> response content streams.
>
> 6) What if client.execute throws exception and it's not handled (so
> neither response content is consumed nor request aborted), will
> connection be returned to the pool, discarded as invalid, or trapped
> eternally exhausting the pool?
>
>
>
> Regards,
> Stevo
>
> On Tue, Jan 11, 2011 at 9:19 PM, Oleg Kalnichevski <ol...@apache.org> wrote:
>> On Tue, 2011-01-11 at 19:17 +0100, Stevo Slavić wrote:
>>> It seems they were.
>>>
>>> On client side of communication I now have:
>>>
>>>
>>>               HttpDelete httpDelete = new HttpDelete(deleteUrl);
>>>
>>>               try {
>>>                       HttpResponse response = client.execute(delete);
>>>                       if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
>>>                               throw new SomeCustomException(response.getStatusLine().getStatusCode(),
>>> response.getStatusLine().getReasonPhrase());
>>>                       }
>>>               } catch (IOException ioe) {
>>>                       throw new SomeCustomException(ioe);
>>>               } finally {
>>>                       if (delete != null) {
>>>                               delete.abort();
>>>                       }
>>>               }
>>>
>>>
>>> Without finally and abort call in it (also with abort just on
>>> IOException in catch block), connections would not get returned to the
>>> pool in regular non-exceptional return. HttpDelete refrence is lost -
>>> not accessible outside of this block/method. This puts responsibility
>>> to the developer to clean up low level resources which weren't
>>> directly created or accessed - I guess it has to be like that.
>>>
>>
>> What is wrong with just this?
>>
>> HttpDelete httpDelete = new HttpDelete(deleteUrl);
>> HttpResponse response = client.execute(httpDelete);
>> HttpEntity entity = response.getEntity();
>> if (entity != null) {
>>    entity.consumeContent();
>> }
>> if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
>>   throw new SomeCustomException();
>> }
>>
>> Oleg
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
>> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>
>

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


Re: HttpDelete and similar could exhaust your http connection pool if not handled properly

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, 2011-01-11 at 22:21 +0100, Stevo Slavić wrote:

> @Oleg
> 
> 4) So it's better / more recommended to consumeContent of response
> entity than to abort request? Is connection considered reusable when
> contentConsumed compared to abort where it gets discarded and new
> connection needs to be instantiated?
> 

Connection cannot be re-used if the request executed over that
connection is aborted. If the entity enclosed with the response is
consumed in an orderly manner the connection remains in a consistent
state and therefore can be potentially re-used.

> 5) I see in 4.1(-beta2-SNAPSHOT) HttpClient.consumeContent is
> deprecated in favor of EntityUtils.consume - there it just gets
> content stream reference and closes it so its performance is let say
> constant - not affected by content size.

Not really. The #close() method always attempts to read the remaining
content and therefore its performance is directly proportional to the
size of the remaining content. In your case the size of the response
content to a DELETE method is likely to be very small. 

>  I think I read, before 4.1,
> abort was more favorable than consumeContent in cases of large
> response content streams.
> 

Both methods have their pros and cons and should be used when
appropriate.

> 6) What if client.execute throws exception and it's not handled (so
> neither response content is consumed nor request aborted), will
> connection be returned to the pool, discarded as invalid, or trapped
> eternally exhausting the pool?
> 

HttpClient automatically discards the underlying connection if request
execution terminates with an exception. One has to worry about resource
deallocation _only_ if a valid response is returned which encloses an
entity. 

Hope this helps

Oleg



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


Re: HttpDelete and similar could exhaust your http connection pool if not handled properly

Posted by Stevo Slavić <ss...@gmail.com>.
@sebb

1) it's "delete" - tried to copy multiple fragments and assemble brief
readable one for the mail, made error, but I hope we understood each
other.

2) delete can be null, HttpClient.execute(HttpUriRequest request)
doesn't state request is final, so it can point to anything after
being passed to execute

3) please don't waste time documenting to be deprecated api


@Oleg

4) So it's better / more recommended to consumeContent of response
entity than to abort request? Is connection considered reusable when
contentConsumed compared to abort where it gets discarded and new
connection needs to be instantiated?

5) I see in 4.1(-beta2-SNAPSHOT) HttpClient.consumeContent is
deprecated in favor of EntityUtils.consume - there it just gets
content stream reference and closes it so its performance is let say
constant - not affected by content size. I think I read, before 4.1,
abort was more favorable than consumeContent in cases of large
response content streams.

6) What if client.execute throws exception and it's not handled (so
neither response content is consumed nor request aborted), will
connection be returned to the pool, discarded as invalid, or trapped
eternally exhausting the pool?



Regards,
Stevo

On Tue, Jan 11, 2011 at 9:19 PM, Oleg Kalnichevski <ol...@apache.org> wrote:
> On Tue, 2011-01-11 at 19:17 +0100, Stevo Slavić wrote:
>> It seems they were.
>>
>> On client side of communication I now have:
>>
>>
>>               HttpDelete httpDelete = new HttpDelete(deleteUrl);
>>
>>               try {
>>                       HttpResponse response = client.execute(delete);
>>                       if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
>>                               throw new SomeCustomException(response.getStatusLine().getStatusCode(),
>> response.getStatusLine().getReasonPhrase());
>>                       }
>>               } catch (IOException ioe) {
>>                       throw new SomeCustomException(ioe);
>>               } finally {
>>                       if (delete != null) {
>>                               delete.abort();
>>                       }
>>               }
>>
>>
>> Without finally and abort call in it (also with abort just on
>> IOException in catch block), connections would not get returned to the
>> pool in regular non-exceptional return. HttpDelete refrence is lost -
>> not accessible outside of this block/method. This puts responsibility
>> to the developer to clean up low level resources which weren't
>> directly created or accessed - I guess it has to be like that.
>>
>
> What is wrong with just this?
>
> HttpDelete httpDelete = new HttpDelete(deleteUrl);
> HttpResponse response = client.execute(httpDelete);
> HttpEntity entity = response.getEntity();
> if (entity != null) {
>    entity.consumeContent();
> }
> if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
>   throw new SomeCustomException();
> }
>
> Oleg
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>
>

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


Re: HttpDelete and similar could exhaust your http connection pool if not handled properly

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, 2011-01-11 at 19:17 +0100, Stevo Slavić wrote:
> It seems they were.
> 
> On client side of communication I now have:
> 
> 
> 		HttpDelete httpDelete = new HttpDelete(deleteUrl);
> 
> 		try {
> 			HttpResponse response = client.execute(delete);
> 			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
> 				throw new SomeCustomException(response.getStatusLine().getStatusCode(),
> response.getStatusLine().getReasonPhrase());
> 			}
> 		} catch (IOException ioe) {
> 			throw new SomeCustomException(ioe);
> 		} finally {
> 			if (delete != null) {
> 				delete.abort();
> 			}
> 		}
> 
> 
> Without finally and abort call in it (also with abort just on
> IOException in catch block), connections would not get returned to the
> pool in regular non-exceptional return. HttpDelete refrence is lost -
> not accessible outside of this block/method. This puts responsibility
> to the developer to clean up low level resources which weren't
> directly created or accessed - I guess it has to be like that.
> 

What is wrong with just this?

HttpDelete httpDelete = new HttpDelete(deleteUrl);
HttpResponse response = client.execute(httpDelete);
HttpEntity entity = response.getEntity();
if (entity != null) {
    entity.consumeContent();
}
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
   throw new SomeCustomException();
}

Oleg



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


Re: HttpDelete and similar could exhaust your http connection pool if not handled properly

Posted by sebb <se...@gmail.com>.
On 11 January 2011 18:17, Stevo Slavić <ss...@gmail.com> wrote:
> It seems they were.
>
> On client side of communication I now have:
>
>
>                HttpDelete httpDelete = new HttpDelete(deleteUrl);

s/httpDelete/delete/ ?

>
>                try {
>                        HttpResponse response = client.execute(delete);
>                        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
>                                throw new SomeCustomException(response.getStatusLine().getStatusCode(),
> response.getStatusLine().getReasonPhrase());
>                        }
>                } catch (IOException ioe) {
>                        throw new SomeCustomException(ioe);
>                } finally {
>                        if (delete != null) {

delete cannot be null here, surely?

>                                delete.abort();
>                        }
>                }
>
>
> Without finally and abort call in it (also with abort just on
> IOException in catch block), connections would not get returned to the
> pool in regular non-exceptional return. HttpDelete refrence is lost -
> not accessible outside of this block/method. This puts responsibility
> to the developer to clean up low level resources which weren't
> directly created or accessed - I guess it has to be like that.

Surely this is similar to closing a file?

But I agree the documentation could do with an example showcasing the
use of HttpEntity#consumeContent().
I'll add that shortly.

> Regards,
> Stevo.
>
>
> On Tue, Jan 11, 2011 at 2:23 PM, Oleg Kalnichevski <ol...@apache.org> wrote:
>> On Tue, 2011-01-11 at 06:11 +0100, Stevo Slavić wrote:
>>> Hello httpclient-users,
>>>
>>> Beginner httpclient user here and this is more note to self and
>>> httpclient users alike. Been hit by http connection pool getting
>>> exhausted, randomly, on production... For few days I've been BMHATW,
>>> suspected even that it's a bug in httpclient 4.0.x, switched to latest
>>> 4.1-beta2-SNAPSHOT which btw works ok for me. With extra logging on
>>> client and server side of communication I've found out that delete
>>> requests didn't return connection back to the pool. After RTFM on
>>> releasing low level resources (see [1]), I've added try-finally around
>>> client.execute(httpDelete) and aborting of httpDelete in finally, and
>>> ta-da, connections would get returned to the pool.
>>>
>>> Regards,
>>> Stevo.
>>>
>>
>> Hi Stevo
>>
>> Did responses to those DELETE methods enclose a response entity? If so,
>> the entity content must be consumed in order for the underlying
>> connection to be released back to the pool.
>>
>> Oleg
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
>> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>
>

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


Re: HttpDelete and similar could exhaust your http connection pool if not handled properly

Posted by Stevo Slavić <ss...@gmail.com>.
It seems they were.

On client side of communication I now have:


		HttpDelete httpDelete = new HttpDelete(deleteUrl);

		try {
			HttpResponse response = client.execute(delete);
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				throw new SomeCustomException(response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase());
			}
		} catch (IOException ioe) {
			throw new SomeCustomException(ioe);
		} finally {
			if (delete != null) {
				delete.abort();
			}
		}


Without finally and abort call in it (also with abort just on
IOException in catch block), connections would not get returned to the
pool in regular non-exceptional return. HttpDelete refrence is lost -
not accessible outside of this block/method. This puts responsibility
to the developer to clean up low level resources which weren't
directly created or accessed - I guess it has to be like that.

Regards,
Stevo.


On Tue, Jan 11, 2011 at 2:23 PM, Oleg Kalnichevski <ol...@apache.org> wrote:
> On Tue, 2011-01-11 at 06:11 +0100, Stevo Slavić wrote:
>> Hello httpclient-users,
>>
>> Beginner httpclient user here and this is more note to self and
>> httpclient users alike. Been hit by http connection pool getting
>> exhausted, randomly, on production... For few days I've been BMHATW,
>> suspected even that it's a bug in httpclient 4.0.x, switched to latest
>> 4.1-beta2-SNAPSHOT which btw works ok for me. With extra logging on
>> client and server side of communication I've found out that delete
>> requests didn't return connection back to the pool. After RTFM on
>> releasing low level resources (see [1]), I've added try-finally around
>> client.execute(httpDelete) and aborting of httpDelete in finally, and
>> ta-da, connections would get returned to the pool.
>>
>> Regards,
>> Stevo.
>>
>
> Hi Stevo
>
> Did responses to those DELETE methods enclose a response entity? If so,
> the entity content must be consumed in order for the underlying
> connection to be released back to the pool.
>
> Oleg
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
>
>

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


Re: HttpDelete and similar could exhaust your http connection pool if not handled properly

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, 2011-01-11 at 06:11 +0100, Stevo Slavić wrote:
> Hello httpclient-users,
> 
> Beginner httpclient user here and this is more note to self and
> httpclient users alike. Been hit by http connection pool getting
> exhausted, randomly, on production... For few days I've been BMHATW,
> suspected even that it's a bug in httpclient 4.0.x, switched to latest
> 4.1-beta2-SNAPSHOT which btw works ok for me. With extra logging on
> client and server side of communication I've found out that delete
> requests didn't return connection back to the pool. After RTFM on
> releasing low level resources (see [1]), I've added try-finally around
> client.execute(httpDelete) and aborting of httpDelete in finally, and
> ta-da, connections would get returned to the pool.
> 
> Regards,
> Stevo.
> 

Hi Stevo

Did responses to those DELETE methods enclose a response entity? If so,
the entity content must be consumed in order for the underlying
connection to be released back to the pool.

Oleg



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