Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 346419 - Build up of pipe file descriptors in Jetty Client 7.4.0
Summary: Build up of pipe file descriptors in Jetty Client 7.4.0
Status: RESOLVED WORKSFORME
Alias: None
Product: Jetty
Classification: RT
Component: client (show other bugs)
Version: unspecified   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 7.2.x   Edit
Assignee: Greg Wilkins CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-19 07:28 EDT by Chris Dumoulin CLA
Modified: 2011-09-21 10:29 EDT (History)
3 users (show)

See Also:


Attachments
test to show it working ok (2.40 KB, text/x-java)
2011-09-20 03:54 EDT, Greg Wilkins CLA
no flags Details
proposed patch (3.97 KB, patch)
2011-09-21 10:25 EDT, Thomas Becker CLA
no flags Details | Diff
proposed patch (8.18 KB, application/octet-stream)
2011-09-21 10:29 EDT, Thomas Becker CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Dumoulin CLA 2011-05-19 07:28:19 EDT
Build Identifier: 7.4.0.v20110414

I've got an application that is using the Jetty HttpClient version 7.4.0, and I'm seeing a buildup of pipe file descriptors when calling HttpClient.send(). This doesn't seem to happen with version 7.2.0.

I'm using "lsof" to see the file descriptors associated with the Java process. When HttpClient.send() is called two more "pipe" files are created and they don't seem to ever go away.

My investigation into this was first triggered by the application not being able to open new connections because of "Too many open files" errors.

Reproducible: Always

Steps to Reproduce:
1.Create an HttpClient
2.Call HttpClient.send()
3.Use lsof to see that two new pipe file descriptors have been created
Comment 1 Chris Dumoulin CLA 2011-07-26 14:21:15 EDT
Is there any update on this issue?
Comment 2 Oatz CLA 2011-09-14 16:02:16 EDT
I am also seeing this issue with Jetty 7.5.1.v20110908, the Sun JVM 1.6.0_26, and Ubuntu 10.04

Our main application uses the HttpClient without issue, but after starting to use the ProxyServlet we begin to encounter this issue. As Chris stated, the two pipe descriptors are opened after the ProxyServlet call to _client.send(exchange). 

I would expect file descriptors to be opened, however after the exchange has been completed these descriptors are not closed / removed until garbage collection occurs. This can lead to a fairly high number of "open" files in busy systems if garbage collection does not occur often. 

We've increased the limit of open files which works around the issue, but if the cleanup of these files is actually happening during garbage collection, I would take that to mean that something is not be closed correctly.

For Reference, we configure the ProxyServlet as follows

ServletContextHandler servlet = new ServletContextHandler(contexts, "/hosts");
for(Entry<String, Address> e : hostMap.entrySet())
{
    String context = "/"+e.getKey();
    Address server = e.getValue();
    ProxyServlet.Transparent proxy = 
           new ProxyServlet.Transparent(
                context,server.getHost(), server.getPort());
    servlet.addServlet(new ServletHolder(proxy), context+"/*");
}

I'll see if I can't work on a simplified testcase to reproduce the issue.
Comment 3 Greg Wilkins CLA 2011-09-20 03:25:46 EDT
Oatz,

are you just using the ProxyServlet as a transparent proxy, or are you using the proxy feature of the HttpClient to talk to your own proxy?
Comment 4 Greg Wilkins CLA 2011-09-20 03:54:29 EDT
Created attachment 203645 [details]
test to show it working ok
Comment 5 Greg Wilkins CLA 2011-09-20 03:55:41 EDT
The attached test shows the number of connections growing then shrinking as you do multiple sends.  lsof verifies that all is working OK.

are you sure you have set and idle time, or max connections per destination?
Comment 6 Chris Dumoulin CLA 2011-09-20 08:02:17 EDT
(In reply to comment #5)
> The attached test shows the number of connections growing then shrinking as you
> do multiple sends.  lsof verifies that all is working OK.
> 
> are you sure you have set and idle time, or max connections per destination?

This is how the HttpClient is being configured in our application:

httpClient = new HttpClient();
httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
httpClient.setTimeout(30000);
httpClient.setConnectTimeout(10000);
httpClient.setMaxRetries(3);
httpClient.setMaxConnectionsPerAddress(10);
httpClient.setThreadPool(new QueuedThreadPool(250));
httpClient.setMaxRedirects(20);

So, no idle timeout is being set, which should mean it defaults to 20 seconds.
Comment 7 Oatz CLA 2011-09-20 10:53:26 EDT
Greg,

We are just using it as a transparent proxy. We use the transparent proxy to periodically retrieve a HTML status page from servers that are behind a firewall.

I hadn't set max connections or idle timeout for the transparent proxy, so I'll do that and see if it makes a difference.

Thanks,
--Oatz
Comment 8 Thomas Becker CLA 2011-09-21 10:25:43 EDT
Created attachment 203775 [details]
proposed patch
Comment 9 Thomas Becker CLA 2011-09-21 10:29:49 EDT
Created attachment 203777 [details]
proposed patch

I can confirm that with my Java Version there's no connection leak. However there could be if channel.socket().connect() fails after establishing a connection. 

I've added two patch files. The first adds a catch for UknownHostException surrounding channel.socket().connect() which takes care for closing the channel. With my JVM it doesn't open a connection before the host is resolved. When applying only the first patch this has the least impact on other code.

The second patch file which should be applied after the first has been will move the channel.close() call to the outer IOException catch block. From my understanding this should be pretty safe to do, so you can apply both patches. Please review.

Additionally the first patch includes a fix for HttpDestination Leak we've when a non existent host is called. Please see the diff for details.