I read here that EntityUtils.consume(httpEntity) will result in releasing the connection back to the connection pool, but when I looked at the source code, I couldn't understand how is that happening. Can someone please point me to the part of the code where EntityUtils.consume(httpEntity) or EntityUtils.toString(httpEntity) is releasing the connection when using the low level Elastic Search Rest Client
?
What happens to the connection if there is a SocketTimeoutException and I don't consume the HttpEntity?
Client-side close and connection release to the Pool (steps)
EntityUtils.consume&EntityUtils.toString> the first one willclose()theinstreamif it fully consumes the entity. The second one will always callinstream.close()in its finally clause.instreamis the name given to the InputStream variable.instream.close()> For this example, the implementation of theInputStreamis aContentInputStream. Theclose()method forces theContentInputStreamto be read till its end by the loop mechanism shown in the code snippet.Following calls to this stream will lead to an
EOFexception.Pool> Checks all pooled resources status. This operation may be triggered by some actions (as a new request), or may be managed by underlying threads. If one resource/stream was closed by the other end, it will get anEOFexception (as the buffer was forced to advance to the end). The spot is marked as invalid.Pool> All invalid spots are recycled. It will remove the closed streams and create new ones, or restore the existing ones without the need of erase+create (depending on the resource type). This means the spot that was holding the stream is avaliable again, with a new stream ready to be used:The connection is released back to the pool. The other end is not using it anymore, so the pool has total control of it. Now the pool is allowed to erase it, restore it, and assign it to another requester..
Example
Let's imagine a
Poolthat manages 3 resources, such asHttpConnections. You already have 3 threads using this pool, so the spots are all occupied.Meanwhile
ThreadZwaits for a connection to be released back to the PoolThreadAfinished its job and closes its connection. ThePoolwill notice this when the status of thePoolEntryis closed. DifferentPoolEntryimplementations will check this is different ways, one of them being getting anEOFexception while trying to read from a stream. Other implementations could have different mechanisms to check if the resource is closed. If thePoolEntrytells that his resource is closed/invalid, thePoolwill recycle this spot. There are two options here:a) Erase and create.
b) Restore.
"Releasing the connection back" could be translated to "now there's an avaliable spot/resource again". The pool can now give a connection to
ThreadZ:consume/toString- connection releaseAll explained above means that calling
close()in theInputStreamwill trigger the connection release.This happens both in
consume(if the entity content is fully consumed) andtoStringmethods:What happens to the connection if there is a SocketTimeoutException and I don't consume the HttpEntity?
As you notice, both methods throw an
IOException, andSocketTimeoutExceptionis inherited from it. It is responsability of the caller to catch this exception and manage to close all resources if such scenario happens. For example:Notice that if a
SocketTimeoutExceptionis thrown, specificPoolEntryimplementations could also check if the resource is invalid without the need of aclose()call. Usingclose()guarantees that thePoolwill recycle the spot after a correct use of it, and can be used as well as a "invalid marker" when you are able to catch a thrown exception.But specific
Poolimplementations will be able to also check if a resource is invalid even if an uncatchedExceptiondidn't let you specifically callclose(), as they would be able to check the status with different mechanisms. For example, checking how many time a connection was inIDLEstate. If this time is superior to a certain treshold marked by thePool, this spot will be recycled without the need of a previousclose()call from the client.This time the
Poolwill be the end that callsclose()on it, avoiding a possibledeadlockin the client side, if this one doesn't manage the max connection time or certain exceptions.