[TYRUS-188] [PERF] WebSocket client library creates too many threads per connection Created: 24/May/13  Updated: 10/Jun/13  Resolved: 10/Jun/13

Status: Resolved
Project: tyrus
Component/s: None
Affects Version/s: 1.0
Fix Version/s: 1.1

Type: Bug Priority: Minor
Reporter: amitagarwal Assignee: Pavel Bucek
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

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.



 Comments   
Comment by amitagarwal [ 24/May/13 ]

Hi Dhiru,

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

Amit.

Comment by Dhiru Pandey [ 24/May/13 ]

Moving this issue to Tyrus project

Comment by Pavel Bucek [ 10/Jun/13 ]

fixed in the trunk

Comment by amitagarwal [ 10/Jun/13 ]

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.

Comment by Pavel Bucek [ 10/Jun/13 ]

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.

Generated at Sat Oct 01 17:00:48 UTC 2016 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.