Issue Details (XML | Word | Printable)

Key: TYRUS-188
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Minor Minor
Assignee: Pavel Bucek
Reporter: amitagarwal
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
tyrus

[PERF] WebSocket client library creates too many threads per connection

Created: 24/May/13 12:04 PM   Updated: 10/Jun/13 11:33 AM   Resolved: 10/Jun/13 09:37 AM
Component/s: None
Affects Version/s: 1.0
Fix Version/s: 1.1

Time Tracking:
Not Specified

Tags:
Participants: amitagarwal, Dhiru Pandey and Pavel Bucek


 Description  « Hide

This issue is present in previous builds too.

We have used WebSocket client API to write WebSocket performance benchmarks. We create tens of thousand of connection for the benchmark. Code looks like this,

Session sessions = new Session[50000];
ClientManager container = ClientManager.createClient();
for (int i = 0 ; i < 50000; i++) {
try { sessions[i] = container.connectToServer(new EchoWebSocketListener(), URI.create(uri)); sessions[i].setMaxIdleTimeout(-1); } catch (Exception e) { System.out.println("Exception thrown while opening connection number: " + i); e.printStackTrace(); }
}

Each call to container.connectToServer() creates plenty of threads (around 50 in number). They are Selector and Worker threads created internally by grizzly code. This hurts benchmark badly as for 50k connections there will be 2.5 million threads. We definitely want to avoid this.

I have traced the problem to org.glassfish.tyrus.container.grizzly.GrizzlyClientSocket.java file.
connect() method of GrizzlyClientSocket class builds/creates transport & starts it for each connection like this,

transport = TCPNIOTransportBuilder.newInstance().build();
transport.start();

This internally creates lots of Selector & Worker threads depending upon number of processors present in the system. This should be avoided by creating transport object only once so that Selector & Worker threads will be shared among all the connections. For now, with my limited knowledge about Grizzly I have made temporary changes into our copy of GrizzlyClientSocket.java but we would like you to modify GrizzlyClientSocket.java appropriately and have it available to us in future versions.



amitagarwal added a comment - 24/May/13 06:22 PM

Hi Dhiru,

Please see who can address this. This is not very urgent but needs to be fixed.

Amit.


Dhiru Pandey added a comment - 24/May/13 06:59 PM

Moving this issue to Tyrus project


Pavel Bucek added a comment - 10/Jun/13 09:37 AM

fixed in the trunk


amitagarwal added a comment - 10/Jun/13 11:24 AM

I have looked at the fix. Fix creates only two threads, one for Selector & another for Worker thread. This definitely is a better implementation than previous one but is not very elegant and does not solve our problem. If we create 50k or 100k connections for our benchmarks, this would create 100k or 200k threads resulting into huge overhead of thread context switching. We expect a better solution.


Pavel Bucek added a comment - 10/Jun/13 11:33 AM

Current change does guarantee same performance for all created clients; I don't want then to share any resources by default. There will be feature for setting custom Worked and Selector ThreadFactory.

I can see what you want to do, but it is far from expected default behavior.