You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by Bill Speirs <bi...@gmail.com> on 2011/10/31 20:26:21 UTC

Too Many Open Files Exception

I'm having an issue with the NIO Reactor. I'm getting the following exception:

org.apache.http.nio.reactor.IOReactorException: Failure accepting connection
        at org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvent(DefaultListeningIOReactor.java:169)
        at org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvents(DefaultListeningIOReactor.java:149)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:370)
        at my code where I call execute()
        at java.lang.Thread.run(Thread.java:662)
Caused by: java.io.IOException: Too many open files
        at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:152)
        at org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvent(DefaultListeningIOReactor.java:165)
        ... 4 more

This code does some complex things including opening two connection
(via HTTP Client) to other services. I believe that I'm correctly
cleaning up those connections by getting the entity in the response to
both, and calling close on the stream.

// first connection to another service
InputStream is = response.getEntity().getContent();

// do stuff with is

is.close();


// second connection to another service

HttpEntity entity = response.getEntity();
		    	
if(entity != null) {
     // close this to release the connection
     entity.getContent().close();
}


That is all I need to do, correct? There isn't anything else to
release the socket is there?

Thanks...

Bill-

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


Re: Too Many Open Files Exception

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, Nov 01, 2011 at 10:09:43AM -0400, Bill Speirs wrote:
> > Good ol' #releaseConnection() method will be back in HttpClient 4.2
> 
> Good. I think that will help to simplify things and cause less
> confusion. I don't know... maybe I'm the only confused one :-)
> 
> > This code is likely to leak connections in case of a runtime (unchecked) exception.
> 
> Good point...
> 
> While we're discussing it, why are there separate classes/interfaces
> in core and client for an HttpRequest:
> 
> org.apache.http.HttpRequest - core
> org.apache.http.client.methods.HttpRequestBase - client
> 
> Would it be beneficial to merge some of this together? Is it that the
> classes in core simply represent a request as it arrives at a server,
> and the methods from client represent the request as it's being made
> to the server. Aren't they about the same?
> 

I personally think they are not. For instance, #abort and #releaseConnection methods make no sense in the server context. The whole concept of connection release is simply not applicable to the server side. At least that is how I see it. 

Oleg

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


Re: Too Many Open Files Exception

Posted by Bill Speirs <bi...@gmail.com>.
> Good ol' #releaseConnection() method will be back in HttpClient 4.2

Good. I think that will help to simplify things and cause less
confusion. I don't know... maybe I'm the only confused one :-)

> This code is likely to leak connections in case of a runtime (unchecked) exception.

Good point...

While we're discussing it, why are there separate classes/interfaces
in core and client for an HttpRequest:

org.apache.http.HttpRequest - core
org.apache.http.client.methods.HttpRequestBase - client

Would it be beneficial to merge some of this together? Is it that the
classes in core simply represent a request as it arrives at a server,
and the methods from client represent the request as it's being made
to the server. Aren't they about the same?

I'm sure there is history here... curious as to what it is and why the
decisions were made.

As always, Oleg thank you very much for your help!

Bill-

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


Re: Too Many Open Files Exception

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, Nov 01, 2011 at 09:29:57AM -0400, Bill Speirs wrote:
> > Correct. The difference is that EntityUtils#consume will try to salvage
> > the underlying connection, whereas HttpUriRequest#abort will not.
> >
> > The important point is to use try-finally to ensure connection release
> > in all cases.
> 
> The problem is that I have two methods to "close" the connection: one
> if everything is fine, another if there is an error/exception. So
> try-catch-finally doesn't really help. I think what I want is the
> following. In the normal case (the try block), I simply get the entity
> and close the input stream on the content. However, if something goes
> wrong I should simply call abort() on the request.
> 
> try {
>   response = client.execute(request);
>   response.getEntity().getContent().close();
> } catch( ... ) {
>   request.abort();
> }
> 
> Does this make sense?
>

Yes, it does, as long as you also catch runtime exceptions.

 
> I suppose moving response.getEntity().getContent().close(); to a
> finally block couldn't hurt, as I don't expect the input stream would
> throw an exception after abort() was called... but it seems messy.
> 
> I guess I'm not sure why there isn't simply a close() method for the
> request which can be called in either case.
> 

Good ol' #releaseConnection() method will be back in HttpClient 4.2


> > HttpClient automatically shuts down the underlying connection in case of
> > an I/O exception including a timeout. The connection manager will evict
> > closed connection immediately upon release.
> 
> That isn't what I'm seeing, although it's tough to reproduce. On two
> separate machines running the same code I'm seeing the following:
> 
> try {
>   HttpResponse response = client.execute(httpHost, request); // throws
> a java.net.SocketTimeoutException
> } catch(IOException e) {
>   request.abort();
> }
> 

This code is likely to leak connections in case of a runtime (unchecked) exception.

Oleg

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


Re: Too Many Open Files Exception

Posted by Bill Speirs <bi...@gmail.com>.
> Correct. The difference is that EntityUtils#consume will try to salvage
> the underlying connection, whereas HttpUriRequest#abort will not.
>
> The important point is to use try-finally to ensure connection release
> in all cases.

The problem is that I have two methods to "close" the connection: one
if everything is fine, another if there is an error/exception. So
try-catch-finally doesn't really help. I think what I want is the
following. In the normal case (the try block), I simply get the entity
and close the input stream on the content. However, if something goes
wrong I should simply call abort() on the request.

try {
  response = client.execute(request);
  response.getEntity().getContent().close();
} catch( ... ) {
  request.abort();
}

Does this make sense?

I suppose moving response.getEntity().getContent().close(); to a
finally block couldn't hurt, as I don't expect the input stream would
throw an exception after abort() was called... but it seems messy.

I guess I'm not sure why there isn't simply a close() method for the
request which can be called in either case.

> HttpClient automatically shuts down the underlying connection in case of
> an I/O exception including a timeout. The connection manager will evict
> closed connection immediately upon release.

That isn't what I'm seeing, although it's tough to reproduce. On two
separate machines running the same code I'm seeing the following:

try {
  HttpResponse response = client.execute(httpHost, request); // throws
a java.net.SocketTimeoutException
} catch(IOException e) {
  request.abort();
}

This code is hit again, and everything hangs. I'm going to try and
enabled debugging so I can find out exactly where it is hanging.

Thanks...

Bill-

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


Re: Too Many Open Files Exception

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Mon, 2011-10-31 at 17:49 -0400, Bill Speirs wrote:
> Yea, I don't think that the IOReactor is the issue... I think something
> else is taking all the sockets and there are none left for the IOReactor to
> call accept.
> 
> Do I need to consume all of the data from the entity before calling close
> on the InputStream?

No, you do not.

>  For error conditions I thought that I should call
> abort().
> 

Correct. The difference is that EntityUtils#consume will try to salvage
the underlying connection, whereas HttpUriRequest#abort will not. 

The important point is to use try-finally to ensure connection release
in all cases. 

> Also, if there is a read timeout on a connection to a host and that
> connection is never closed, what happens when I ask the connection manager
> for a connection to that same host/route? Would it still hand-out that bad
> connection?
> 

HttpClient automatically shuts down the underlying connection in case of
an I/O exception including a timeout. The connection manager will evict
closed connection immediately upon release.

Hope this helps

Oleg

> Bill-
> On Oct 31, 2011 5:31 PM, "Oleg Kalnichevski" <ol...@apache.org> wrote:
> 
> > On Mon, 2011-10-31 at 15:26 -0400, Bill Speirs wrote:
> > > I'm having an issue with the NIO Reactor. I'm getting the following
> > exception:
> > >
> > > org.apache.http.nio.reactor.IOReactorException: Failure accepting
> > connection
> > >         at
> > org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvent(DefaultListeningIOReactor.java:169)
> > >         at
> > org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvents(DefaultListeningIOReactor.java:149)
> > >         at
> > org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:370)
> > >         at my code where I call execute()
> > >         at java.lang.Thread.run(Thread.java:662)
> > > Caused by: java.io.IOException: Too many open files
> > >         at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
> > >         at
> > sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:152)
> > >         at
> > org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvent(DefaultListeningIOReactor.java:165)
> > >         ... 4 more
> > >
> >
> > Bill
> >
> > The NIO reactor is not necessarily the culprit. Connection descriptors
> > may be leaking elsewhere.
> >
> > > This code does some complex things including opening two connection
> > > (via HTTP Client) to other services. I believe that I'm correctly
> > > cleaning up those connections by getting the entity in the response to
> > > both, and calling close on the stream.
> > >
> > > // first connection to another service
> > > InputStream is = response.getEntity().getContent();
> > >
> > > // do stuff with is
> > >
> > > is.close();
> > >
> > >
> > > // second connection to another service
> > >
> > > HttpEntity entity = response.getEntity();
> > >
> > > if(entity != null) {
> > >      // close this to release the connection
> > >      entity.getContent().close();
> > > }
> > >
> > >
> > > That is all I need to do, correct? There isn't anything else to
> > > release the socket is there?
> > >
> >
> > You should probably be releasing connection resources from a try-finally
> > clause. This would ensure that resources get correctly released in case
> > of an abnormal situation: non 2xx response, runtime exception, etc
> >
> > HttpResponse response = httpclient.execute(httpget, context);
> > try {
> > // process response
> > } finally {
> >    EntityUtils.consume(response.getEntity());
> > }
> >
> > Oleg
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> > For additional commands, e-mail: dev-help@hc.apache.org
> >
> >



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


Re: Too Many Open Files Exception

Posted by Bill Speirs <bi...@gmail.com>.
Yea, I don't think that the IOReactor is the issue... I think something
else is taking all the sockets and there are none left for the IOReactor to
call accept.

Do I need to consume all of the data from the entity before calling close
on the InputStream? For error conditions I thought that I should call
abort().

Also, if there is a read timeout on a connection to a host and that
connection is never closed, what happens when I ask the connection manager
for a connection to that same host/route? Would it still hand-out that bad
connection?

Bill-
On Oct 31, 2011 5:31 PM, "Oleg Kalnichevski" <ol...@apache.org> wrote:

> On Mon, 2011-10-31 at 15:26 -0400, Bill Speirs wrote:
> > I'm having an issue with the NIO Reactor. I'm getting the following
> exception:
> >
> > org.apache.http.nio.reactor.IOReactorException: Failure accepting
> connection
> >         at
> org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvent(DefaultListeningIOReactor.java:169)
> >         at
> org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvents(DefaultListeningIOReactor.java:149)
> >         at
> org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:370)
> >         at my code where I call execute()
> >         at java.lang.Thread.run(Thread.java:662)
> > Caused by: java.io.IOException: Too many open files
> >         at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
> >         at
> sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:152)
> >         at
> org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvent(DefaultListeningIOReactor.java:165)
> >         ... 4 more
> >
>
> Bill
>
> The NIO reactor is not necessarily the culprit. Connection descriptors
> may be leaking elsewhere.
>
> > This code does some complex things including opening two connection
> > (via HTTP Client) to other services. I believe that I'm correctly
> > cleaning up those connections by getting the entity in the response to
> > both, and calling close on the stream.
> >
> > // first connection to another service
> > InputStream is = response.getEntity().getContent();
> >
> > // do stuff with is
> >
> > is.close();
> >
> >
> > // second connection to another service
> >
> > HttpEntity entity = response.getEntity();
> >
> > if(entity != null) {
> >      // close this to release the connection
> >      entity.getContent().close();
> > }
> >
> >
> > That is all I need to do, correct? There isn't anything else to
> > release the socket is there?
> >
>
> You should probably be releasing connection resources from a try-finally
> clause. This would ensure that resources get correctly released in case
> of an abnormal situation: non 2xx response, runtime exception, etc
>
> HttpResponse response = httpclient.execute(httpget, context);
> try {
> // process response
> } finally {
>    EntityUtils.consume(response.getEntity());
> }
>
> Oleg
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> For additional commands, e-mail: dev-help@hc.apache.org
>
>

Re: Too Many Open Files Exception

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Mon, 2011-10-31 at 15:26 -0400, Bill Speirs wrote:
> I'm having an issue with the NIO Reactor. I'm getting the following exception:
> 
> org.apache.http.nio.reactor.IOReactorException: Failure accepting connection
>         at org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvent(DefaultListeningIOReactor.java:169)
>         at org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvents(DefaultListeningIOReactor.java:149)
>         at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:370)
>         at my code where I call execute()
>         at java.lang.Thread.run(Thread.java:662)
> Caused by: java.io.IOException: Too many open files
>         at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
>         at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:152)
>         at org.apache.http.impl.nio.reactor.DefaultListeningIOReactor.processEvent(DefaultListeningIOReactor.java:165)
>         ... 4 more
> 

Bill

The NIO reactor is not necessarily the culprit. Connection descriptors
may be leaking elsewhere. 

> This code does some complex things including opening two connection
> (via HTTP Client) to other services. I believe that I'm correctly
> cleaning up those connections by getting the entity in the response to
> both, and calling close on the stream.
> 
> // first connection to another service
> InputStream is = response.getEntity().getContent();
> 
> // do stuff with is
> 
> is.close();
> 
> 
> // second connection to another service
> 
> HttpEntity entity = response.getEntity();
> 		    	
> if(entity != null) {
>      // close this to release the connection
>      entity.getContent().close();
> }
> 
> 
> That is all I need to do, correct? There isn't anything else to
> release the socket is there?
> 

You should probably be releasing connection resources from a try-finally
clause. This would ensure that resources get correctly released in case
of an abnormal situation: non 2xx response, runtime exception, etc 

HttpResponse response = httpclient.execute(httpget, context);
try {
// process response
} finally {
    EntityUtils.consume(response.getEntity());
}

Oleg



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